@stack-spot/citric-react 0.1.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 (345) hide show
  1. package/dist/citric.css +2580 -0
  2. package/dist/components/Accordion.d.ts +33 -0
  3. package/dist/components/Accordion.d.ts.map +1 -0
  4. package/dist/components/Accordion.js +19 -0
  5. package/dist/components/Accordion.js.map +1 -0
  6. package/dist/components/Alert.d.ts +11 -0
  7. package/dist/components/Alert.d.ts.map +1 -0
  8. package/dist/components/Alert.js +5 -0
  9. package/dist/components/Alert.js.map +1 -0
  10. package/dist/components/AsyncContent.d.ts +30 -0
  11. package/dist/components/AsyncContent.d.ts.map +1 -0
  12. package/dist/components/AsyncContent.js +33 -0
  13. package/dist/components/AsyncContent.js.map +1 -0
  14. package/dist/components/Avatar.d.ts +22 -0
  15. package/dist/components/Avatar.d.ts.map +1 -0
  16. package/dist/components/Avatar.js +9 -0
  17. package/dist/components/Avatar.js.map +1 -0
  18. package/dist/components/AvatarGroup.d.ts +25 -0
  19. package/dist/components/AvatarGroup.d.ts.map +1 -0
  20. package/dist/components/AvatarGroup.js +9 -0
  21. package/dist/components/AvatarGroup.js.map +1 -0
  22. package/dist/components/Badge.d.ts +18 -0
  23. package/dist/components/Badge.d.ts.map +1 -0
  24. package/dist/components/Badge.js +7 -0
  25. package/dist/components/Badge.js.map +1 -0
  26. package/dist/components/Blockquote.d.ts +5 -0
  27. package/dist/components/Blockquote.d.ts.map +1 -0
  28. package/dist/components/Blockquote.js +4 -0
  29. package/dist/components/Blockquote.js.map +1 -0
  30. package/dist/components/Breadcrumb.d.ts +12 -0
  31. package/dist/components/Breadcrumb.d.ts.map +1 -0
  32. package/dist/components/Breadcrumb.js +8 -0
  33. package/dist/components/Breadcrumb.js.map +1 -0
  34. package/dist/components/Button.d.ts +42 -0
  35. package/dist/components/Button.d.ts.map +1 -0
  36. package/dist/components/Button.js +25 -0
  37. package/dist/components/Button.js.map +1 -0
  38. package/dist/components/Card.d.ts +19 -0
  39. package/dist/components/Card.d.ts.map +1 -0
  40. package/dist/components/Card.js +5 -0
  41. package/dist/components/Card.js.map +1 -0
  42. package/dist/components/Checkbox.d.ts +14 -0
  43. package/dist/components/Checkbox.d.ts.map +1 -0
  44. package/dist/components/Checkbox.js +7 -0
  45. package/dist/components/Checkbox.js.map +1 -0
  46. package/dist/components/CheckboxGroup.d.ts +53 -0
  47. package/dist/components/CheckboxGroup.d.ts.map +1 -0
  48. package/dist/components/CheckboxGroup.js +17 -0
  49. package/dist/components/CheckboxGroup.js.map +1 -0
  50. package/dist/components/Circle.d.ts +18 -0
  51. package/dist/components/Circle.d.ts.map +1 -0
  52. package/dist/components/Circle.js +5 -0
  53. package/dist/components/Circle.js.map +1 -0
  54. package/dist/components/CitricComponent.d.ts +14 -0
  55. package/dist/components/CitricComponent.d.ts.map +1 -0
  56. package/dist/components/CitricComponent.js +15 -0
  57. package/dist/components/CitricComponent.js.map +1 -0
  58. package/dist/components/Divider.d.ts +14 -0
  59. package/dist/components/Divider.d.ts.map +1 -0
  60. package/dist/components/Divider.js +5 -0
  61. package/dist/components/Divider.js.map +1 -0
  62. package/dist/components/ErrorBoundary.d.ts +32 -0
  63. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  64. package/dist/components/ErrorBoundary.js +46 -0
  65. package/dist/components/ErrorBoundary.js.map +1 -0
  66. package/dist/components/ErrorMessage.d.ts +4 -0
  67. package/dist/components/ErrorMessage.d.ts.map +1 -0
  68. package/dist/components/ErrorMessage.js +7 -0
  69. package/dist/components/ErrorMessage.js.map +1 -0
  70. package/dist/components/FallbackBoundary.d.ts +13 -0
  71. package/dist/components/FallbackBoundary.d.ts.map +1 -0
  72. package/dist/components/FallbackBoundary.js +11 -0
  73. package/dist/components/FallbackBoundary.js.map +1 -0
  74. package/dist/components/Favorite.d.ts +23 -0
  75. package/dist/components/Favorite.d.ts.map +1 -0
  76. package/dist/components/Favorite.js +5 -0
  77. package/dist/components/Favorite.js.map +1 -0
  78. package/dist/components/FieldGroup.d.ts +14 -0
  79. package/dist/components/FieldGroup.d.ts.map +1 -0
  80. package/dist/components/FieldGroup.js +5 -0
  81. package/dist/components/FieldGroup.js.map +1 -0
  82. package/dist/components/Form.d.ts +5 -0
  83. package/dist/components/Form.d.ts.map +1 -0
  84. package/dist/components/Form.js +6 -0
  85. package/dist/components/Form.js.map +1 -0
  86. package/dist/components/FormGroup.d.ts +22 -0
  87. package/dist/components/FormGroup.d.ts.map +1 -0
  88. package/dist/components/FormGroup.js +8 -0
  89. package/dist/components/FormGroup.js.map +1 -0
  90. package/dist/components/IconBox.d.ts +46 -0
  91. package/dist/components/IconBox.d.ts.map +1 -0
  92. package/dist/components/IconBox.js +29 -0
  93. package/dist/components/IconBox.js.map +1 -0
  94. package/dist/components/Input.d.ts +15 -0
  95. package/dist/components/Input.d.ts.map +1 -0
  96. package/dist/components/Input.js +18 -0
  97. package/dist/components/Input.js.map +1 -0
  98. package/dist/components/Link.d.ts +20 -0
  99. package/dist/components/Link.d.ts.map +1 -0
  100. package/dist/components/Link.js +21 -0
  101. package/dist/components/Link.js.map +1 -0
  102. package/dist/components/LoadingPanel.d.ts +2 -0
  103. package/dist/components/LoadingPanel.d.ts.map +1 -0
  104. package/dist/components/LoadingPanel.js +5 -0
  105. package/dist/components/LoadingPanel.js.map +1 -0
  106. package/dist/components/MenuOverlay/Menu.d.ts +6 -0
  107. package/dist/components/MenuOverlay/Menu.d.ts.map +1 -0
  108. package/dist/components/MenuOverlay/Menu.js +100 -0
  109. package/dist/components/MenuOverlay/Menu.js.map +1 -0
  110. package/dist/components/MenuOverlay/context.d.ts +6 -0
  111. package/dist/components/MenuOverlay/context.d.ts.map +1 -0
  112. package/dist/components/MenuOverlay/context.js +16 -0
  113. package/dist/components/MenuOverlay/context.js.map +1 -0
  114. package/dist/components/MenuOverlay/index.d.ts +3 -0
  115. package/dist/components/MenuOverlay/index.d.ts.map +1 -0
  116. package/dist/components/MenuOverlay/index.js +23 -0
  117. package/dist/components/MenuOverlay/index.js.map +1 -0
  118. package/dist/components/MenuOverlay/keyboard.d.ts +2 -0
  119. package/dist/components/MenuOverlay/keyboard.d.ts.map +1 -0
  120. package/dist/components/MenuOverlay/keyboard.js +66 -0
  121. package/dist/components/MenuOverlay/keyboard.js.map +1 -0
  122. package/dist/components/MenuOverlay/types.d.ts +166 -0
  123. package/dist/components/MenuOverlay/types.d.ts.map +1 -0
  124. package/dist/components/MenuOverlay/types.js +2 -0
  125. package/dist/components/MenuOverlay/types.js.map +1 -0
  126. package/dist/components/Overlay/context.d.ts +4 -0
  127. package/dist/components/Overlay/context.d.ts.map +1 -0
  128. package/dist/components/Overlay/context.js +7 -0
  129. package/dist/components/Overlay/context.js.map +1 -0
  130. package/dist/components/Overlay/index.d.ts +14 -0
  131. package/dist/components/Overlay/index.d.ts.map +1 -0
  132. package/dist/components/Overlay/index.js +120 -0
  133. package/dist/components/Overlay/index.js.map +1 -0
  134. package/dist/components/Overlay/types.d.ts +67 -0
  135. package/dist/components/Overlay/types.d.ts.map +1 -0
  136. package/dist/components/Overlay/types.js +2 -0
  137. package/dist/components/Overlay/types.js.map +1 -0
  138. package/dist/components/Pagination.d.ts +28 -0
  139. package/dist/components/Pagination.d.ts.map +1 -0
  140. package/dist/components/Pagination.js +30 -0
  141. package/dist/components/Pagination.js.map +1 -0
  142. package/dist/components/ProgressBar.d.ts +12 -0
  143. package/dist/components/ProgressBar.d.ts.map +1 -0
  144. package/dist/components/ProgressBar.js +7 -0
  145. package/dist/components/ProgressBar.js.map +1 -0
  146. package/dist/components/ProgressCircular.d.ts +16 -0
  147. package/dist/components/ProgressCircular.d.ts.map +1 -0
  148. package/dist/components/ProgressCircular.js +7 -0
  149. package/dist/components/ProgressCircular.js.map +1 -0
  150. package/dist/components/RadioGroup.d.ts +48 -0
  151. package/dist/components/RadioGroup.d.ts.map +1 -0
  152. package/dist/components/RadioGroup.js +17 -0
  153. package/dist/components/RadioGroup.js.map +1 -0
  154. package/dist/components/Rating.d.ts +13 -0
  155. package/dist/components/Rating.d.ts.map +1 -0
  156. package/dist/components/Rating.js +4 -0
  157. package/dist/components/Rating.js.map +1 -0
  158. package/dist/components/Select/RichSelect.d.ts +5 -0
  159. package/dist/components/Select/RichSelect.d.ts.map +1 -0
  160. package/dist/components/Select/RichSelect.js +152 -0
  161. package/dist/components/Select/RichSelect.js.map +1 -0
  162. package/dist/components/Select/SimpleSelect.d.ts +5 -0
  163. package/dist/components/Select/SimpleSelect.d.ts.map +1 -0
  164. package/dist/components/Select/SimpleSelect.js +24 -0
  165. package/dist/components/Select/SimpleSelect.js.map +1 -0
  166. package/dist/components/Select/index.d.ts +4 -0
  167. package/dist/components/Select/index.d.ts.map +1 -0
  168. package/dist/components/Select/index.js +7 -0
  169. package/dist/components/Select/index.js.map +1 -0
  170. package/dist/components/Select/types.d.ts +118 -0
  171. package/dist/components/Select/types.d.ts.map +1 -0
  172. package/dist/components/Select/types.js +2 -0
  173. package/dist/components/Select/types.js.map +1 -0
  174. package/dist/components/SelectBox.d.ts +65 -0
  175. package/dist/components/SelectBox.d.ts.map +1 -0
  176. package/dist/components/SelectBox.js +26 -0
  177. package/dist/components/SelectBox.js.map +1 -0
  178. package/dist/components/Skeleton.d.ts +30 -0
  179. package/dist/components/Skeleton.d.ts.map +1 -0
  180. package/dist/components/Skeleton.js +5 -0
  181. package/dist/components/Skeleton.js.map +1 -0
  182. package/dist/components/Slider.d.ts +32 -0
  183. package/dist/components/Slider.d.ts.map +1 -0
  184. package/dist/components/Slider.js +19 -0
  185. package/dist/components/Slider.js.map +1 -0
  186. package/dist/components/SmartTable.d.ts +87 -0
  187. package/dist/components/SmartTable.d.ts.map +1 -0
  188. package/dist/components/SmartTable.js +16 -0
  189. package/dist/components/SmartTable.js.map +1 -0
  190. package/dist/components/Stepper.d.ts +52 -0
  191. package/dist/components/Stepper.d.ts.map +1 -0
  192. package/dist/components/Stepper.js +53 -0
  193. package/dist/components/Stepper.js.map +1 -0
  194. package/dist/components/Switch.d.ts +10 -0
  195. package/dist/components/Switch.d.ts.map +1 -0
  196. package/dist/components/Switch.js +7 -0
  197. package/dist/components/Switch.js.map +1 -0
  198. package/dist/components/Table.d.ts +106 -0
  199. package/dist/components/Table.d.ts.map +1 -0
  200. package/dist/components/Table.js +86 -0
  201. package/dist/components/Table.js.map +1 -0
  202. package/dist/components/Tabs/TabController.d.ts +11 -0
  203. package/dist/components/Tabs/TabController.d.ts.map +1 -0
  204. package/dist/components/Tabs/TabController.js +39 -0
  205. package/dist/components/Tabs/TabController.js.map +1 -0
  206. package/dist/components/Tabs/index.d.ts +5 -0
  207. package/dist/components/Tabs/index.d.ts.map +1 -0
  208. package/dist/components/Tabs/index.js +37 -0
  209. package/dist/components/Tabs/index.js.map +1 -0
  210. package/dist/components/Tabs/types.d.ts +46 -0
  211. package/dist/components/Tabs/types.d.ts.map +1 -0
  212. package/dist/components/Tabs/types.js +2 -0
  213. package/dist/components/Tabs/types.js.map +1 -0
  214. package/dist/components/Tabs/utils.d.ts +3 -0
  215. package/dist/components/Tabs/utils.d.ts.map +1 -0
  216. package/dist/components/Tabs/utils.js +5 -0
  217. package/dist/components/Tabs/utils.js.map +1 -0
  218. package/dist/components/Text.d.ts +27 -0
  219. package/dist/components/Text.d.ts.map +1 -0
  220. package/dist/components/Text.js +45 -0
  221. package/dist/components/Text.js.map +1 -0
  222. package/dist/components/Textarea.d.ts +8 -0
  223. package/dist/components/Textarea.d.ts.map +1 -0
  224. package/dist/components/Textarea.js +4 -0
  225. package/dist/components/Textarea.js.map +1 -0
  226. package/dist/components/Tooltip.d.ts +25 -0
  227. package/dist/components/Tooltip.d.ts.map +1 -0
  228. package/dist/components/Tooltip.js +18 -0
  229. package/dist/components/Tooltip.js.map +1 -0
  230. package/dist/components/layout.d.ts +46 -0
  231. package/dist/components/layout.d.ts.map +1 -0
  232. package/dist/components/layout.js +18 -0
  233. package/dist/components/layout.js.map +1 -0
  234. package/dist/context/CitricContext.d.ts +3 -0
  235. package/dist/context/CitricContext.d.ts.map +1 -0
  236. package/dist/context/CitricContext.js +3 -0
  237. package/dist/context/CitricContext.js.map +1 -0
  238. package/dist/context/CitricProvider.d.ts +9 -0
  239. package/dist/context/CitricProvider.d.ts.map +1 -0
  240. package/dist/context/CitricProvider.js +8 -0
  241. package/dist/context/CitricProvider.js.map +1 -0
  242. package/dist/context/hooks.d.ts +2 -0
  243. package/dist/context/hooks.d.ts.map +1 -0
  244. package/dist/context/hooks.js +6 -0
  245. package/dist/context/hooks.js.map +1 -0
  246. package/dist/index.d.ts +48 -0
  247. package/dist/index.d.ts.map +1 -0
  248. package/dist/index.js +48 -0
  249. package/dist/index.js.map +1 -0
  250. package/dist/overlay.d.ts +83 -0
  251. package/dist/overlay.d.ts.map +1 -0
  252. package/dist/overlay.js +199 -0
  253. package/dist/overlay.js.map +1 -0
  254. package/dist/theme.css +419 -0
  255. package/dist/types.d.ts +175 -0
  256. package/dist/types.d.ts.map +1 -0
  257. package/dist/types.js +2 -0
  258. package/dist/types.js.map +1 -0
  259. package/dist/utils/ValueController.d.ts +10 -0
  260. package/dist/utils/ValueController.d.ts.map +1 -0
  261. package/dist/utils/ValueController.js +32 -0
  262. package/dist/utils/ValueController.js.map +1 -0
  263. package/dist/utils/acessibility.d.ts +52 -0
  264. package/dist/utils/acessibility.d.ts.map +1 -0
  265. package/dist/utils/acessibility.js +80 -0
  266. package/dist/utils/acessibility.js.map +1 -0
  267. package/dist/utils/css.d.ts +12 -0
  268. package/dist/utils/css.d.ts.map +1 -0
  269. package/dist/utils/css.js +72 -0
  270. package/dist/utils/css.js.map +1 -0
  271. package/dist/utils/options.d.ts +3 -0
  272. package/dist/utils/options.d.ts.map +1 -0
  273. package/dist/utils/options.js +7 -0
  274. package/dist/utils/options.js.map +1 -0
  275. package/package.json +51 -0
  276. package/scripts/build-css.ts +49 -0
  277. package/src/components/Accordion.tsx +74 -0
  278. package/src/components/Alert.tsx +16 -0
  279. package/src/components/AsyncContent.tsx +54 -0
  280. package/src/components/Avatar.tsx +34 -0
  281. package/src/components/AvatarGroup.tsx +40 -0
  282. package/src/components/Badge.tsx +28 -0
  283. package/src/components/Blockquote.tsx +9 -0
  284. package/src/components/Breadcrumb.tsx +24 -0
  285. package/src/components/Button.tsx +88 -0
  286. package/src/components/Card.tsx +32 -0
  287. package/src/components/Checkbox.tsx +36 -0
  288. package/src/components/CheckboxGroup.tsx +93 -0
  289. package/src/components/Circle.tsx +26 -0
  290. package/src/components/CitricComponent.ts +34 -0
  291. package/src/components/Divider.tsx +22 -0
  292. package/src/components/ErrorBoundary.tsx +62 -0
  293. package/src/components/ErrorMessage.tsx +11 -0
  294. package/src/components/FallbackBoundary.tsx +29 -0
  295. package/src/components/Favorite.tsx +37 -0
  296. package/src/components/FieldGroup.tsx +22 -0
  297. package/src/components/Form.tsx +17 -0
  298. package/src/components/FormGroup.tsx +45 -0
  299. package/src/components/IconBox.tsx +78 -0
  300. package/src/components/Input.tsx +32 -0
  301. package/src/components/Link.tsx +40 -0
  302. package/src/components/LoadingPanel.tsx +8 -0
  303. package/src/components/MenuOverlay/Menu.tsx +157 -0
  304. package/src/components/MenuOverlay/context.ts +20 -0
  305. package/src/components/MenuOverlay/index.tsx +35 -0
  306. package/src/components/MenuOverlay/keyboard.ts +60 -0
  307. package/src/components/MenuOverlay/types.ts +178 -0
  308. package/src/components/Overlay/context.ts +10 -0
  309. package/src/components/Overlay/index.tsx +137 -0
  310. package/src/components/Overlay/types.ts +71 -0
  311. package/src/components/Pagination.tsx +90 -0
  312. package/src/components/ProgressBar.tsx +25 -0
  313. package/src/components/ProgressCircular.tsx +29 -0
  314. package/src/components/RadioGroup.tsx +87 -0
  315. package/src/components/Rating.tsx +25 -0
  316. package/src/components/Select/RichSelect.tsx +214 -0
  317. package/src/components/Select/SimpleSelect.tsx +66 -0
  318. package/src/components/Select/index.tsx +8 -0
  319. package/src/components/Select/types.ts +121 -0
  320. package/src/components/SelectBox.tsx +134 -0
  321. package/src/components/Skeleton.tsx +41 -0
  322. package/src/components/Slider.tsx +77 -0
  323. package/src/components/SmartTable.tsx +148 -0
  324. package/src/components/Stepper.tsx +142 -0
  325. package/src/components/Switch.tsx +29 -0
  326. package/src/components/Table.tsx +219 -0
  327. package/src/components/Tabs/TabController.ts +40 -0
  328. package/src/components/Tabs/index.tsx +64 -0
  329. package/src/components/Tabs/types.ts +48 -0
  330. package/src/components/Tabs/utils.ts +6 -0
  331. package/src/components/Text.ts +75 -0
  332. package/src/components/Textarea.tsx +12 -0
  333. package/src/components/Tooltip.tsx +53 -0
  334. package/src/components/layout.tsx +53 -0
  335. package/src/context/CitricContext.tsx +4 -0
  336. package/src/context/CitricProvider.tsx +14 -0
  337. package/src/context/hooks.ts +6 -0
  338. package/src/index.ts +47 -0
  339. package/src/overlay.ts +276 -0
  340. package/src/types.ts +226 -0
  341. package/src/utils/ValueController.ts +28 -0
  342. package/src/utils/acessibility.ts +92 -0
  343. package/src/utils/css.ts +106 -0
  344. package/src/utils/options.ts +7 -0
  345. package/tsconfig.json +10 -0
@@ -0,0 +1,219 @@
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
3
+ import { useEffect, useRef } from 'react'
4
+ import { HTMLExtension } from '../types'
5
+ import { applyCSSVariable } from '../utils/css'
6
+ import { CitricComponent } from './CitricComponent'
7
+
8
+ export interface BaseTableProps {
9
+ /**
10
+ * The overall table's appearance. Includes a default configuration for every other styling related prop.
11
+ *
12
+ * @default 'spaced'
13
+ */
14
+ appearance?: 'stripped' | 'spaced',
15
+ /**
16
+ * Whether or not to color each row a different color. Only valid when appearance is "spaced".
17
+ *
18
+ * @default false
19
+ */
20
+ stripped?: boolean,
21
+ /**
22
+ * If true, there's no spacing between rows. Only valid when appearance is "spaced".
23
+ *
24
+ * @default false
25
+ */
26
+ compressed?: boolean,
27
+ /**
28
+ * Shows an outer border for the whole table.
29
+ *
30
+ * @default "true if appearance is 'stripped', false otherwise"
31
+ */
32
+ showBorders?: boolean,
33
+ /**
34
+ * Shows borders in each of the rows.
35
+ *
36
+ * @default false
37
+ */
38
+ showRowBorders?: boolean,
39
+ /**
40
+ * Shows borders in the header.
41
+ *
42
+ * @default "false if appearance is 'stripped', true otherwise"
43
+ */
44
+ showHeaderBorders?: boolean,
45
+ /**
46
+ * Whether or not the table borders are rounded.
47
+ *
48
+ * @default true
49
+ */
50
+ rounded?: boolean,
51
+ /**
52
+ * Whether or not each row in the table have rounded borders.
53
+ *
54
+ * @default "false if appearance is 'stripped', true otherwise"
55
+ */
56
+ roundedRows?: boolean,
57
+ /**
58
+ * If true, all headers are uppercase.
59
+ *
60
+ * @default false
61
+ */
62
+ uppercaseHeader?: boolean,
63
+ /**
64
+ * Allows rows to act as accordions. To create an accordion row, use `<tbody>` to group two `<tr>` elements, where the first is the actual
65
+ * row and the second is the collapsible content of the row. The row with the collapsible content must be defined as `<Tr accordion>`.
66
+ *
67
+ * @default false
68
+ */
69
+ accordionRows?: boolean,
70
+ }
71
+
72
+ export type SortingDirection = 'asc' | 'desc'
73
+
74
+ interface BaseThProps {
75
+ /**
76
+ * Which is the current direction of the sorting? Only relevant if 'onSort' is set.
77
+ *
78
+ * @default 'desc'
79
+ */
80
+ direction?: SortingDirection,
81
+ /**
82
+ * What to do when the header is clicked (sorting).
83
+ */
84
+ onSort?: (value: SortingDirection | undefined) => void,
85
+ }
86
+
87
+ interface BaseTrProps {
88
+ /**
89
+ * True if this table is an accordion, false otherwise.
90
+ *
91
+ * @default false
92
+ */
93
+ accordion?: boolean,
94
+ /**
95
+ * If the next row is an accordion, what should make it expand or contract? A click on a button in the last column or a click anywhere in
96
+ * the row?
97
+ *
98
+ * @default 'button'
99
+ */
100
+ accordionTrigger?: 'button' | 'row',
101
+ /**
102
+ * Sets the maximum height of this accordion. Only valid if `accordion` is true.
103
+ *
104
+ * @default '200px'
105
+ */
106
+ accordionMaxHeight?: string,
107
+ }
108
+
109
+ export type TableProps = HTMLExtension<'table', BaseTableProps>
110
+ export type ThProps = HTMLExtension<'th', BaseThProps>
111
+ export type TrProps = HTMLExtension<'tr', BaseTrProps>
112
+
113
+ export const Table = ({
114
+ appearance, stripped, compressed, showBorders, showHeaderBorders, showRowBorders, rounded, roundedRows, uppercaseHeader, className,
115
+ children, accordionRows, ...props
116
+ }: TableProps) => {
117
+ const classes = listToClass([
118
+ className,
119
+ stripped && 'stripped',
120
+ compressed && 'compressed',
121
+ showBorders && 'bordered',
122
+ showHeaderBorders === false && 'borderless-header',
123
+ showRowBorders && 'bordered-rows',
124
+ rounded === false && 'square',
125
+ roundedRows === false && 'square-rows',
126
+ uppercaseHeader && 'uppercase-header',
127
+ accordionRows && 'accordion-rows',
128
+ ])
129
+ return (
130
+ <CitricComponent tag="table" component="table" data-appearance={appearance} className={classes} {...props}>
131
+ {children}
132
+ </CitricComponent>
133
+ )
134
+ }
135
+
136
+ export const Th = ({ direction, onSort, children, className, ...props }: ThProps) => {
137
+ const t = useTranslate(dictionary)
138
+ let tip: string | undefined
139
+ const label = typeof children === 'string' ? children : undefined
140
+ if (onSort && !direction) tip = label ? `${label}. ${t.sortAscending}` : t.sortAscending
141
+ if (onSort && direction === 'asc') tip = label ? `${label}. ${t.sortDescending}` : t.sortDescending
142
+ if (onSort && direction === 'desc') tip = label ? `${label}. ${t.sortNone}` : t.sortNone
143
+
144
+ function handleSort() {
145
+ if (!direction) onSort?.('asc')
146
+ else if (direction === 'asc') onSort?.('desc')
147
+ else onSort?.(undefined)
148
+ }
149
+
150
+ return (
151
+ <th
152
+ className={listToClass([onSort && 'sortable', direction, className])}
153
+ onClick={onSort? handleSort : undefined}
154
+ onKeyDown={onSort ? (e => e.key === 'Enter' && handleSort()) : undefined}
155
+ aria-label={tip}
156
+ tabIndex={onSort ? 0 : undefined}
157
+ {...props}
158
+ >
159
+ {children}
160
+ </th>
161
+ )
162
+ }
163
+
164
+ export const Tr = ({ accordion, accordionTrigger, accordionMaxHeight, children, className, style, onClick, ...props }: TrProps) => {
165
+ const ref = useRef<HTMLTableRowElement | null>(null)
166
+
167
+ useEffect(() => {
168
+ if (!accordion) return
169
+ const checkbox = ref.current?.closest('tbody')?.querySelector('td:last-child input[aria-controls]')
170
+ if (checkbox instanceof HTMLElement) {
171
+ const onChange = (e: Event) => {
172
+ if (!ref.current || !(e.target instanceof HTMLInputElement)) return
173
+ if (e.target.checked) {
174
+ ref.current.setAttribute('aria-hidden', 'false')
175
+ ref.current.removeAttribute('inert')
176
+ } else {
177
+ ref.current.setAttribute('aria-hidden', 'true')
178
+ ref.current.setAttribute('inert', 'true')
179
+ }
180
+ }
181
+ checkbox.addEventListener('change', onChange)
182
+ return () => checkbox.removeEventListener('change', onChange)
183
+ }
184
+ }, [ref.current])
185
+
186
+ return (
187
+ <tr
188
+ ref={ref}
189
+ {...props}
190
+ className={listToClass([className, accordion && 'accordion', accordionTrigger === 'row' && 'clickable'])}
191
+ onClick={accordionTrigger === 'row'
192
+ ? (e) => {
193
+ const checkbox = ref.current?.querySelector('td:last-child input[aria-controls]')
194
+ if (checkbox instanceof HTMLInputElement && e.target !== checkbox) checkbox.click()
195
+ onClick?.(e)
196
+ }
197
+ : onClick
198
+ }
199
+ style={applyCSSVariable(style, 'max-height', accordionMaxHeight)}
200
+ aria-hidden={accordion}
201
+ {...(accordion ? { inert: 'true' } : {})}
202
+ >
203
+ {children}
204
+ </tr>
205
+ )
206
+ }
207
+
208
+ const dictionary = {
209
+ en: {
210
+ sortAscending: 'Click to sort in ascending order.',
211
+ sortDescending: 'Click to sort in descending order.',
212
+ sortNone: 'Click to remove sorting.',
213
+ },
214
+ pt: {
215
+ sortAscending: 'Clique para ordenar em ordem crescente.',
216
+ sortDescending: 'Clique para ordenar em ordem decrescente.',
217
+ sortNone: 'Clique para remover a ordenação.',
218
+ },
219
+ } satisfies Dictionary
@@ -0,0 +1,40 @@
1
+ import { ValueController } from '../../utils/ValueController'
2
+
3
+ export class TabController<Key extends string> extends ValueController<Key> {
4
+ private tabOrder: Key[]
5
+
6
+ constructor(tabOrder: Key[], value: Key) {
7
+ super(value)
8
+ this.tabOrder = tabOrder
9
+ }
10
+
11
+ private getCurrentIndex() {
12
+ return this.tabOrder.findIndex(t => t === this.value)
13
+ }
14
+
15
+ hasNext(): boolean {
16
+ const current = this.getCurrentIndex()
17
+ return current > -1 && current + 1 < this.tabOrder.length
18
+ }
19
+
20
+ hasPrevious(): boolean {
21
+ const current = this.getCurrentIndex()
22
+ return current > -1 && current - 1 >= 0
23
+ }
24
+
25
+ next(): boolean {
26
+ if (this.hasNext()) {
27
+ this.setValue(this.tabOrder[this.getCurrentIndex() + 1])
28
+ return true
29
+ }
30
+ return false
31
+ }
32
+
33
+ previous(): boolean {
34
+ if (this.hasPrevious()) {
35
+ this.setValue(this.tabOrder[this.getCurrentIndex() - 1])
36
+ return true
37
+ }
38
+ return false
39
+ }
40
+ }
@@ -0,0 +1,64 @@
1
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
2
+ import { createContext, Suspense, useContext, useEffect, useMemo, useState } from 'react'
3
+ import { CitricComponent } from '../CitricComponent'
4
+ import { ErrorBoundary } from '../ErrorBoundary'
5
+ import { ProgressCircular } from '../ProgressCircular'
6
+ import { Center } from '../layout'
7
+ import { TabController } from './TabController'
8
+ import { TabsProps } from './types'
9
+ import { findSelectedIndex } from './utils'
10
+
11
+ const ctx = createContext<TabController<any> | undefined>(undefined)
12
+
13
+ export function Tabs<Key extends string>({ tabs, value, onChange, controller: ctrl, ...props }: TabsProps<Key>) {
14
+ const controller = useMemo(() => ctrl ?? new TabController<Key>(tabs.map(t => t.key), value || tabs[0]?.key), [])
15
+ const t = useTranslate(dictionary)
16
+ const [selectedIndex, setSelectedIndex] = useState(findSelectedIndex(tabs, controller.getValue()))
17
+
18
+ useEffect(() => {
19
+ if (value) controller.setValue(value)
20
+ }, [value])
21
+
22
+ useEffect(() => controller.onChange((v) => {
23
+ setSelectedIndex(findSelectedIndex(tabs, v))
24
+ onChange?.(v)
25
+ }), [tabs])
26
+
27
+ const nav = useMemo(
28
+ () => tabs.map(({ key, label, disabled }, index) => (
29
+ <label key={key}>
30
+ <input type="radio" role="tab" checked={index === selectedIndex} onChange={() => controller.setValue(key)} disabled={disabled} />
31
+ {label || key}
32
+ </label>
33
+ )),
34
+ [tabs, selectedIndex],
35
+ )
36
+
37
+ return (
38
+ <ctx.Provider value={controller}>
39
+ <CitricComponent tag="div" component="tabs" {...props}>
40
+ <nav>{nav}</nav>
41
+ <section>
42
+ <ErrorBoundary key={selectedIndex} message={t.error}>
43
+ <Suspense fallback={<Center style={{ padding: '20px' }}><ProgressCircular /></Center>}>
44
+ {selectedIndex === -1 ? null : tabs[selectedIndex]?.content}
45
+ </Suspense>
46
+ </ErrorBoundary>
47
+ </section>
48
+ </CitricComponent>
49
+ </ctx.Provider>
50
+ )
51
+ }
52
+
53
+ export function useTabController<Key extends string = string>(): TabController<Key> | undefined {
54
+ return useContext(ctx)
55
+ }
56
+
57
+ const dictionary = {
58
+ en: {
59
+ error: 'Error while loading the tab.',
60
+ },
61
+ pt: {
62
+ error: 'Ocorreu um erro ao carregar a aba.',
63
+ },
64
+ } satisfies Dictionary
@@ -0,0 +1,48 @@
1
+ import { HTMLExtension, WithColorPalette, WithColorScheme } from '../../types'
2
+ import { TabController } from './TabController'
3
+
4
+ export interface Tab<Key extends string> {
5
+ /**
6
+ * A unique identifier for the tab.
7
+ */
8
+ key: Key,
9
+ /**
10
+ * The tab's label. Will be the "key" if not provided.
11
+ */
12
+ label?: string,
13
+ /**
14
+ * The tab's content. This can be a suspended component.
15
+ *
16
+ * Attention: consider using React's lazy loading to render the tab view.
17
+ */
18
+ content: React.ReactNode,
19
+ /**
20
+ * Whether or not this tab is disabled.
21
+ *
22
+ * @default false
23
+ */
24
+ disabled?: boolean,
25
+ }
26
+
27
+ export interface BaseTabsProps<Key extends string> extends WithColorScheme, WithColorPalette {
28
+ /**
29
+ * The tabs to render.
30
+ */
31
+ tabs: Tab<Key>[],
32
+ /**
33
+ * The key of the current tab. Use this only if you intend to control the tabs from the outside.
34
+ */
35
+ value?: Key,
36
+ /**
37
+ * What to do when the tab changes. Use this only if you intend to control the tabs from the outside.
38
+ *
39
+ * @param key the key of the selected tab.
40
+ */
41
+ onChange?: (key: Key) => void,
42
+ /**
43
+ * A tab-controller, useful if you want to control the tabs outside the component context.
44
+ */
45
+ controller?: TabController<Key>,
46
+ }
47
+
48
+ export type TabsProps<Key extends string> = HTMLExtension<'div', BaseTabsProps<Key>, 'children' | 'value' | 'onChange'>
@@ -0,0 +1,6 @@
1
+ import { Tab } from './types'
2
+
3
+ export function findSelectedIndex<Key extends string>(tabs: Tab<Key>[], selectedTabKey: Key) {
4
+ const index = tabs.findIndex(t => t.key === selectedTabKey)
5
+ return index === -1 ? 0 : index
6
+ }
@@ -0,0 +1,75 @@
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { createElement } from 'react'
3
+ import { HTMLExtension, TextAppearance, WithColor } from '../types'
4
+ import { applyColor, applyTextAppearance } from '../utils/css'
5
+
6
+ type SupportedTags = 'span' | 'small' | 'p' | `h${1|2|3|4|5|6}` | 'pre'
7
+
8
+ export interface BaseTextProps<T extends SupportedTags = SupportedTags> extends WithColor {
9
+ /**
10
+ * If "tag" is not defined, it will be based on the value of "appearance".
11
+ * If neither "appearance" or "tag" are defined, the tag will be "p".
12
+ */
13
+ tag?: T,
14
+ /**
15
+ * If "appearance" is not defined, it will be based on the value of "tag".
16
+ * If neither "appearance" or "tag" are defined, the appearance will be inherited from the parent HTML element.
17
+ */
18
+ appearance?: TextAppearance,
19
+ /**
20
+ * Add default margins to the text.
21
+ *
22
+ * @default false
23
+ */
24
+ showMargins?: boolean,
25
+ }
26
+
27
+ export type TextProps<T extends SupportedTags> = HTMLExtension<T, BaseTextProps<T>>
28
+
29
+ const tagToAppearance: Record<SupportedTags, TextAppearance | undefined> = {
30
+ h1: 'h1',
31
+ h2: 'h2',
32
+ h3: 'h3',
33
+ h4: 'h4',
34
+ h5: 'h5',
35
+ h6: 'h6',
36
+ span: undefined,
37
+ small: 'microtext1',
38
+ p: 'body2',
39
+ pre: 'code2',
40
+ }
41
+
42
+ const appearanceToTag: Record<TextAppearance, SupportedTags> = {
43
+ h1: 'h1',
44
+ h2: 'h2',
45
+ h3: 'h3',
46
+ h4: 'h4',
47
+ h5: 'h5',
48
+ h6: 'h6',
49
+ body1: 'p',
50
+ body2: 'p',
51
+ code1: 'pre',
52
+ code2: 'pre',
53
+ display1: 'h1',
54
+ microtext1: 'small',
55
+ overheader1: 'p',
56
+ overheader2: 'p',
57
+ subtitle1: 'p',
58
+ subtitle2: 'p',
59
+ subtitle3: 'p',
60
+ subtitle4: 'p',
61
+ }
62
+
63
+ export function Text<T extends SupportedTags>({ tag, appearance, color, showMargins, style, className, children, ...props }: TextProps<T>) {
64
+ const renderedTag = tag || appearanceToTag[appearance || 'body2']
65
+ const renderedAppearance = appearance || (tag ? tagToAppearance[tag] : undefined)
66
+ return createElement(
67
+ renderedTag,
68
+ {
69
+ className: applyTextAppearance(listToClass([className, showMargins && 'text-with-margins']), renderedAppearance),
70
+ style: applyColor(style, color),
71
+ ...props,
72
+ },
73
+ children,
74
+ )
75
+ }
@@ -0,0 +1,12 @@
1
+ import { HTMLExtension, WithColorScheme } from '../types'
2
+ import { CitricComponent } from './CitricComponent'
3
+
4
+ export interface BaseTextareaProps extends WithColorScheme {
5
+ value?: string,
6
+ onChange?: (value: string) => void,
7
+ }
8
+
9
+ export type TextareaProps = HTMLExtension<'textarea', BaseTextareaProps, 'onChange'>
10
+
11
+ export const Textarea = ({ value, onChange, ...props }: TextareaProps) =>
12
+ <CitricComponent tag="textarea" component="textarea" value={value} onChange={e => onChange?.(e.target.value)} {...props} />
@@ -0,0 +1,53 @@
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { useRef } from 'react'
3
+ import { HTMLExtension, WithColorPalette, WithColorScheme } from '../types'
4
+ import { Overlay } from './Overlay'
5
+ import { BaseOverlayProps } from './Overlay/types'
6
+
7
+ export interface BaseTooltipProps extends
8
+ Omit<BaseOverlayProps<'div'>, 'tag' | 'onRenderChild' | 'reference'>, WithColorPalette, WithColorScheme {
9
+ /**
10
+ * Whether or not to show the tooltip's arrow.
11
+ *
12
+ * @default true
13
+ */
14
+ showArrow?: boolean,
15
+ /**
16
+ * The unique id of the HTML element to be created to show the tooltip. If not provided, a random number will be used.
17
+ */
18
+ tooltipId?: string,
19
+ /**
20
+ * Makes the tooltip text compact, centering it better when it's a single line.
21
+ *
22
+ * Effectively, it makes the line height equals to 1 and applies a slightly larger padding.
23
+ *
24
+ * @default true
25
+ */
26
+ compact?: boolean,
27
+ }
28
+
29
+ export type TooltipProps = HTMLExtension<'div', BaseTooltipProps, 'children' | 'content'>
30
+
31
+ export const Tooltip = (
32
+ { tooltipId, children, showArrow = true, compact = true, attributes, colorScheme, colorPalette, ...props }: TooltipProps,
33
+ ) => {
34
+ const id = useRef(tooltipId || `${Math.random()}`)
35
+ return (
36
+ <Overlay
37
+ attributes={{
38
+ className: listToClass([attributes?.className, showArrow && 'with-arrow', compact && 'compact']),
39
+ style: { margin: '6px', ...attributes?.style },
40
+ role: 'tooltip',
41
+ id: id.current,
42
+ 'data-citric': 'tooltip',
43
+ 'data-color-scheme': colorScheme,
44
+ 'data-color-palette': colorPalette,
45
+ ...attributes,
46
+ }}
47
+ onRenderChild={e => e.setAttribute('aria-describedby', id.current)}
48
+ {...props}
49
+ >
50
+ {children}
51
+ </Overlay>
52
+ )
53
+ }
@@ -0,0 +1,53 @@
1
+ import { listToClass } from '@stack-spot/portal-theme'
2
+ import { createElement } from 'react'
3
+ import { HTMLExtension, WithStyleShortcuts } from '../types'
4
+ import { applyStyles } from '../utils/css'
5
+
6
+ export const layout = {
7
+ center: 'center',
8
+ row: 'row',
9
+ column: 'column',
10
+ }
11
+
12
+ export interface BaseLayoutProps<T extends keyof React.JSX.IntrinsicElements> extends WithStyleShortcuts {
13
+ /**
14
+ * HTML tag to render.
15
+ *
16
+ * @default 'div'
17
+ */
18
+ tag?: T,
19
+ }
20
+
21
+ export interface BaseRowProps<T extends keyof React.JSX.IntrinsicElements> extends BaseLayoutProps<T> {
22
+ /**
23
+ * Whether or not to center items horizontally.
24
+ *
25
+ * @default true
26
+ */
27
+ center?: boolean,
28
+ }
29
+
30
+ export interface BaseColumnProps<T extends keyof React.JSX.IntrinsicElements> extends BaseLayoutProps<T> {
31
+ /**
32
+ * Whether or not to center items vertically.
33
+ *
34
+ * @default false
35
+ */
36
+ center?: boolean,
37
+ }
38
+
39
+ export type CenterProps<T extends keyof React.JSX.IntrinsicElements> = HTMLExtension<T, BaseLayoutProps<T>>
40
+ export type RowProps<T extends keyof React.JSX.IntrinsicElements> = HTMLExtension<T, BaseRowProps<T>>
41
+ export type ColumnProps<T extends keyof React.JSX.IntrinsicElements> = HTMLExtension<T, BaseColumnProps<T>>
42
+
43
+ export function Center<T extends keyof React.JSX.IntrinsicElements = 'div'>({ tag, className, ...props }: CenterProps<T>) {
44
+ return createElement(tag || 'div', { className: listToClass(['center', className]), ...applyStyles(props) })
45
+ }
46
+
47
+ export function Row<T extends keyof React.JSX.IntrinsicElements = 'div'>({ tag, className, center, ...props }: RowProps<T>) {
48
+ return createElement(tag || 'div', { className: listToClass(['row', center === false && 'no-center', className]), ...applyStyles(props) })
49
+ }
50
+
51
+ export function Column<T extends keyof React.JSX.IntrinsicElements = 'div'>({ tag, className, center, ...props }: ColumnProps<T>) {
52
+ return createElement(tag || 'div', { className: listToClass(['column', center && 'center', className]), ...applyStyles(props) })
53
+ }
@@ -0,0 +1,4 @@
1
+ import { createContext } from 'react'
2
+ import { CitricController } from '../types'
3
+
4
+ export const CitricContext = createContext<CitricController | undefined>(undefined)
@@ -0,0 +1,14 @@
1
+ import { FallbackBoundary } from '../components/FallbackBoundary'
2
+ import { CitricController } from '../types'
3
+ import { CitricContext } from './CitricContext'
4
+
5
+ /**
6
+ * An optional provider for customizing the behavior of the Design System. This accepts a CitricController as its value.
7
+ */
8
+ export const CitricProvider = ({ children, value }: { children: React.ReactNode, value?: CitricController }) => (
9
+ <CitricContext.Provider value={value}>
10
+ <FallbackBoundary>
11
+ {children}
12
+ </FallbackBoundary>
13
+ </CitricContext.Provider>
14
+ )
@@ -0,0 +1,6 @@
1
+ import { useContext } from 'react'
2
+ import { CitricContext } from './CitricContext'
3
+
4
+ export function useCitricController() {
5
+ return useContext(CitricContext)
6
+ }
package/src/index.ts ADDED
@@ -0,0 +1,47 @@
1
+ export * from './components/Accordion'
2
+ export * from './components/Alert'
3
+ export * from './components/Avatar'
4
+ export * from './components/AvatarGroup'
5
+ export * from './components/Badge'
6
+ export * from './components/Blockquote'
7
+ export * from './components/Breadcrumb'
8
+ export * from './components/Button'
9
+ export * from './components/Card'
10
+ export * from './components/Checkbox'
11
+ export * from './components/CheckboxGroup'
12
+ export * from './components/Circle'
13
+ export * from './components/CitricComponent'
14
+ export * from './components/Divider'
15
+ export * from './components/ErrorBoundary'
16
+ export * from './components/Favorite'
17
+ export * from './components/FieldGroup'
18
+ export * from './components/Form'
19
+ export * from './components/FormGroup'
20
+ export * from './components/IconBox'
21
+ export * from './components/Input'
22
+ export * from './components/layout'
23
+ export * from './components/Link'
24
+ export * from './components/MenuOverlay'
25
+ export * from './components/MenuOverlay/types'
26
+ export * from './components/Overlay'
27
+ export * from './components/Overlay/types'
28
+ export * from './components/Pagination'
29
+ export * from './components/ProgressBar'
30
+ export * from './components/ProgressCircular'
31
+ export * from './components/RadioGroup'
32
+ export * from './components/Rating'
33
+ export * from './components/Select'
34
+ export * from './components/SelectBox'
35
+ export * from './components/Skeleton'
36
+ export * from './components/Slider'
37
+ export * from './components/SmartTable'
38
+ export * from './components/Stepper'
39
+ export * from './components/Switch'
40
+ export * from './components/Table'
41
+ export * from './components/Tabs'
42
+ export * from './components/Tabs/TabController'
43
+ export * from './components/Tabs/types'
44
+ export * from './components/Text'
45
+ export * from './components/Textarea'
46
+ export * from './components/Tooltip'
47
+ export * from './utils/ValueController'