@swan-io/lake 1.0.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 (288) hide show
  1. package/HISTORY.md +3 -0
  2. package/LICENSE +21 -0
  3. package/README.md +49 -0
  4. package/package.json +60 -0
  5. package/src/components/Alert.d.ts +10 -0
  6. package/src/components/Alert.js +36 -0
  7. package/src/components/AppOpeningAnimation.d.ts +10 -0
  8. package/src/components/AppOpeningAnimation.js +50 -0
  9. package/src/components/AutoWidthImage.d.ts +8 -0
  10. package/src/components/AutoWidthImage.js +26 -0
  11. package/src/components/Avatar.d.ts +7 -0
  12. package/src/components/Avatar.js +42 -0
  13. package/src/components/BorderedButton.d.ts +16 -0
  14. package/src/components/BorderedButton.js +98 -0
  15. package/src/components/BorderedIcon.d.ts +12 -0
  16. package/src/components/BorderedIcon.js +25 -0
  17. package/src/components/BottomPanel.d.ts +9 -0
  18. package/src/components/BottomPanel.js +94 -0
  19. package/src/components/Box.d.ts +65 -0
  20. package/src/components/Box.js +31 -0
  21. package/src/components/Breadcrumbs.d.ts +18 -0
  22. package/src/components/Breadcrumbs.js +362 -0
  23. package/src/components/Button.d.ts +15 -0
  24. package/src/components/Button.js +83 -0
  25. package/src/components/Caption.d.ts +6 -0
  26. package/src/components/Caption.js +11 -0
  27. package/src/components/Checkbox.d.ts +12 -0
  28. package/src/components/Checkbox.js +83 -0
  29. package/src/components/ChoicePicker.d.ts +11 -0
  30. package/src/components/ChoicePicker.js +99 -0
  31. package/src/components/Combobox.d.ts +29 -0
  32. package/src/components/Combobox.js +182 -0
  33. package/src/components/FailureIcon.d.ts +8 -0
  34. package/src/components/FailureIcon.js +4 -0
  35. package/src/components/FileTile.d.ts +11 -0
  36. package/src/components/FileTile.js +37 -0
  37. package/src/components/Fill.d.ts +8 -0
  38. package/src/components/Fill.js +24 -0
  39. package/src/components/FilterChooser.d.ts +15 -0
  40. package/src/components/FilterChooser.js +52 -0
  41. package/src/components/Filters.d.ts +57 -0
  42. package/src/components/Filters.js +229 -0
  43. package/src/components/FixedListView.d.ts +104 -0
  44. package/src/components/FixedListView.js +821 -0
  45. package/src/components/FixedListViewCells.d.ts +55 -0
  46. package/src/components/FixedListViewCells.js +157 -0
  47. package/src/components/Flag.d.ts +8 -0
  48. package/src/components/Flag.js +36 -0
  49. package/src/components/FlowPresentation.d.ts +12 -0
  50. package/src/components/FlowPresentation.js +70 -0
  51. package/src/components/FocusTrap.d.ts +16 -0
  52. package/src/components/FocusTrap.js +90 -0
  53. package/src/components/Form.d.ts +8 -0
  54. package/src/components/Form.js +17 -0
  55. package/src/components/FullViewportLayer.d.ts +7 -0
  56. package/src/components/FullViewportLayer.js +91 -0
  57. package/src/components/Grid.d.ts +13 -0
  58. package/src/components/Grid.js +33 -0
  59. package/src/components/Heading.d.ts +61 -0
  60. package/src/components/Heading.js +27 -0
  61. package/src/components/Icon.d.ts +191 -0
  62. package/src/components/Icon.js +11 -0
  63. package/src/components/Input.d.ts +34 -0
  64. package/src/components/Input.js +115 -0
  65. package/src/components/InputError.d.ts +8 -0
  66. package/src/components/InputError.js +16 -0
  67. package/src/components/Label.d.ts +10 -0
  68. package/src/components/Label.js +19 -0
  69. package/src/components/LakeAlert.d.ts +14 -0
  70. package/src/components/LakeAlert.js +75 -0
  71. package/src/components/LakeButton.d.ts +36 -0
  72. package/src/components/LakeButton.js +171 -0
  73. package/src/components/LakeCheckbox.d.ts +16 -0
  74. package/src/components/LakeCheckbox.js +54 -0
  75. package/src/components/LakeCombobox.d.ts +28 -0
  76. package/src/components/LakeCombobox.js +166 -0
  77. package/src/components/LakeCopyButton.d.ts +10 -0
  78. package/src/components/LakeCopyButton.js +16 -0
  79. package/src/components/LakeDownloadButton.d.ts +8 -0
  80. package/src/components/LakeDownloadButton.js +6 -0
  81. package/src/components/LakeHeading.d.ts +10 -0
  82. package/src/components/LakeHeading.js +19 -0
  83. package/src/components/LakeLabel.d.ts +19 -0
  84. package/src/components/LakeLabel.js +43 -0
  85. package/src/components/LakeModal.d.ts +14 -0
  86. package/src/components/LakeModal.js +132 -0
  87. package/src/components/LakeRadio.d.ts +9 -0
  88. package/src/components/LakeRadio.js +44 -0
  89. package/src/components/LakeScrollView.d.ts +10 -0
  90. package/src/components/LakeScrollView.js +35 -0
  91. package/src/components/LakeSearchField.d.ts +10 -0
  92. package/src/components/LakeSearchField.js +111 -0
  93. package/src/components/LakeSelect.d.ts +30 -0
  94. package/src/components/LakeSelect.js +183 -0
  95. package/src/components/LakeSlider.d.ts +12 -0
  96. package/src/components/LakeSlider.js +31 -0
  97. package/src/components/LakeStepper.d.ts +21 -0
  98. package/src/components/LakeStepper.js +134 -0
  99. package/src/components/LakeText.d.ts +19 -0
  100. package/src/components/LakeText.js +20 -0
  101. package/src/components/LakeTextInput.d.ts +36 -0
  102. package/src/components/LakeTextInput.js +154 -0
  103. package/src/components/LakeTooltip.d.ts +24 -0
  104. package/src/components/LakeTooltip.js +188 -0
  105. package/src/components/Link.d.ts +138 -0
  106. package/src/components/Link.js +23 -0
  107. package/src/components/ListRightPanel.d.ts +17 -0
  108. package/src/components/ListRightPanel.js +79 -0
  109. package/src/components/LoadingView.d.ts +9 -0
  110. package/src/components/LoadingView.js +24 -0
  111. package/src/components/Modal.d.ts +12 -0
  112. package/src/components/Modal.js +80 -0
  113. package/src/components/MultiSelect.d.ts +27 -0
  114. package/src/components/MultiSelect.js +223 -0
  115. package/src/components/MultilineInput.d.ts +15 -0
  116. package/src/components/MultilineInput.js +55 -0
  117. package/src/components/Picker.d.ts +26 -0
  118. package/src/components/Picker.js +116 -0
  119. package/src/components/PlainListView.d.ts +36 -0
  120. package/src/components/PlainListView.js +208 -0
  121. package/src/components/Popover.d.ts +23 -0
  122. package/src/components/Popover.js +147 -0
  123. package/src/components/PopoverContent.d.ts +8 -0
  124. package/src/components/PopoverContent.js +9 -0
  125. package/src/components/Portal.d.ts +7 -0
  126. package/src/components/Portal.js +9 -0
  127. package/src/components/Pressable.d.ts +348 -0
  128. package/src/components/Pressable.js +91 -0
  129. package/src/components/ProgressBar.d.ts +11 -0
  130. package/src/components/ProgressBar.js +46 -0
  131. package/src/components/ProjectEnvTag.d.ts +7 -0
  132. package/src/components/ProjectEnvTag.js +12 -0
  133. package/src/components/QuickActions.d.ts +15 -0
  134. package/src/components/QuickActions.js +38 -0
  135. package/src/components/RadioGroup.d.ts +16 -0
  136. package/src/components/RadioGroup.js +34 -0
  137. package/src/components/ReadOnlyFieldList.d.ts +6 -0
  138. package/src/components/ReadOnlyFieldList.js +8 -0
  139. package/src/components/ResponsiveContainer.d.ts +13 -0
  140. package/src/components/ResponsiveContainer.js +23 -0
  141. package/src/components/RightPanel.d.ts +10 -0
  142. package/src/components/RightPanel.js +102 -0
  143. package/src/components/SegmentedControl.d.ts +19 -0
  144. package/src/components/SegmentedControl.js +74 -0
  145. package/src/components/Separator.d.ts +10 -0
  146. package/src/components/Separator.js +19 -0
  147. package/src/components/SidebarNavigationTracker.d.ts +13 -0
  148. package/src/components/SidebarNavigationTracker.js +93 -0
  149. package/src/components/Slider.d.ts +11 -0
  150. package/src/components/Slider.js +119 -0
  151. package/src/components/SmsOpeningAnimation.d.ts +8 -0
  152. package/src/components/SmsOpeningAnimation.js +52 -0
  153. package/src/components/Space.d.ts +10 -0
  154. package/src/components/Space.js +23 -0
  155. package/src/components/Stack.d.ts +12 -0
  156. package/src/components/Stack.js +23 -0
  157. package/src/components/StepDots.d.ts +7 -0
  158. package/src/components/StepDots.js +24 -0
  159. package/src/components/Stepper.d.ts +9 -0
  160. package/src/components/Stepper.js +67 -0
  161. package/src/components/SuccessIcon.d.ts +8 -0
  162. package/src/components/SuccessIcon.js +4 -0
  163. package/src/components/Svg.d.ts +145 -0
  164. package/src/components/Svg.js +24 -0
  165. package/src/components/SwanLogo.d.ts +8 -0
  166. package/src/components/SwanLogo.js +11 -0
  167. package/src/components/Switch.d.ts +9 -0
  168. package/src/components/Switch.js +74 -0
  169. package/src/components/TabView.d.ts +16 -0
  170. package/src/components/TabView.js +398 -0
  171. package/src/components/Table.d.ts +34 -0
  172. package/src/components/Table.js +79 -0
  173. package/src/components/Tag.d.ts +17 -0
  174. package/src/components/Tag.js +76 -0
  175. package/src/components/Tile.d.ts +34 -0
  176. package/src/components/Tile.js +130 -0
  177. package/src/components/TilePlaceholder.d.ts +6 -0
  178. package/src/components/TilePlaceholder.js +51 -0
  179. package/src/components/ToastStack.d.ts +2 -0
  180. package/src/components/ToastStack.js +96 -0
  181. package/src/components/Tooltip.d.ts +18 -0
  182. package/src/components/Tooltip.js +162 -0
  183. package/src/components/TransitionGroupView.d.ts +12 -0
  184. package/src/components/TransitionGroupView.js +43 -0
  185. package/src/components/TransitionView.d.ts +12 -0
  186. package/src/components/TransitionView.js +43 -0
  187. package/src/components/WithCurrentColor.d.ts +12 -0
  188. package/src/components/WithCurrentColor.js +65 -0
  189. package/src/components/WithPartnerAccentColor.d.ts +7 -0
  190. package/src/components/WithPartnerAccentColor.js +91 -0
  191. package/src/constants/colors.d.ts +42 -0
  192. package/src/constants/colors.js +42 -0
  193. package/src/constants/commonStyles.d.ts +66 -0
  194. package/src/constants/commonStyles.js +45 -0
  195. package/src/constants/design.d.ts +168 -0
  196. package/src/constants/design.js +564 -0
  197. package/src/constants/insets.d.ts +10 -0
  198. package/src/constants/insets.js +22 -0
  199. package/src/constants/typography.d.ts +26 -0
  200. package/src/constants/typography.js +54 -0
  201. package/src/hooks/useAnimatedValue.d.ts +2 -0
  202. package/src/hooks/useAnimatedValue.js +3 -0
  203. package/src/hooks/useBodyClassName.d.ts +3 -0
  204. package/src/hooks/useBodyClassName.js +14 -0
  205. package/src/hooks/useBoolean.d.ts +8 -0
  206. package/src/hooks/useBoolean.js +12 -0
  207. package/src/hooks/useComputedColors.d.ts +10 -0
  208. package/src/hooks/useComputedColors.js +42 -0
  209. package/src/hooks/useDebounce.d.ts +1 -0
  210. package/src/hooks/useDebounce.js +12 -0
  211. package/src/hooks/useDisclosure.d.ts +8 -0
  212. package/src/hooks/useDisclosure.js +12 -0
  213. package/src/hooks/useFirstMountState.d.ts +1 -0
  214. package/src/hooks/useFirstMountState.js +9 -0
  215. package/src/hooks/useForceableState.d.ts +1 -0
  216. package/src/hooks/useForceableState.js +6 -0
  217. package/src/hooks/useHover.d.ts +11 -0
  218. package/src/hooks/useHover.js +4 -0
  219. package/src/hooks/useInterval.d.ts +1 -0
  220. package/src/hooks/useInterval.js +11 -0
  221. package/src/hooks/useLazyRef.d.ts +2 -0
  222. package/src/hooks/useLazyRef.js +9 -0
  223. package/src/hooks/useMergeRefs.d.ts +2 -0
  224. package/src/hooks/useMergeRefs.js +5 -0
  225. package/src/hooks/useNativeProp.d.ts +2 -0
  226. package/src/hooks/useNativeProp.js +9 -0
  227. package/src/hooks/useOutsideClick.d.ts +8 -0
  228. package/src/hooks/useOutsideClick.js +54 -0
  229. package/src/hooks/usePersistedState.d.ts +1 -0
  230. package/src/hooks/usePersistedState.js +21 -0
  231. package/src/hooks/usePressEvents.d.ts +31 -0
  232. package/src/hooks/usePressEvents.js +4 -0
  233. package/src/hooks/usePreviousValue.d.ts +1 -0
  234. package/src/hooks/usePreviousValue.js +8 -0
  235. package/src/hooks/useResponsive.d.ts +7 -0
  236. package/src/hooks/useResponsive.js +20 -0
  237. package/src/hooks/useUpdateEffect.d.ts +2 -0
  238. package/src/hooks/useUpdateEffect.js +10 -0
  239. package/src/hooks/useUrqlMutation.d.ts +4 -0
  240. package/src/hooks/useUrqlMutation.js +30 -0
  241. package/src/hooks/useUrqlQuery.d.ts +19 -0
  242. package/src/hooks/useUrqlQuery.js +73 -0
  243. package/src/state/toasts.d.ts +21 -0
  244. package/src/state/toasts.js +61 -0
  245. package/src/utils/__tests__/array.test.d.ts +1 -0
  246. package/src/utils/__tests__/array.test.js +127 -0
  247. package/src/utils/__tests__/base64.test.d.ts +1 -0
  248. package/src/utils/__tests__/base64.test.js +27 -0
  249. package/src/utils/__tests__/function.test.d.ts +1 -0
  250. package/src/utils/__tests__/function.test.js +36 -0
  251. package/src/utils/__tests__/object.test.d.ts +1 -0
  252. package/src/utils/__tests__/object.test.js +17 -0
  253. package/src/utils/__tests__/rifm.test.d.ts +1 -0
  254. package/src/utils/__tests__/rifm.test.js +124 -0
  255. package/src/utils/__tests__/string.test.d.ts +1 -0
  256. package/src/utils/__tests__/string.test.js +16 -0
  257. package/src/utils/a11y.d.ts +1 -0
  258. package/src/utils/a11y.js +18 -0
  259. package/src/utils/array.d.ts +6 -0
  260. package/src/utils/array.js +71 -0
  261. package/src/utils/base64.d.ts +2 -0
  262. package/src/utils/base64.js +20 -0
  263. package/src/utils/file.d.ts +2 -0
  264. package/src/utils/file.js +10 -0
  265. package/src/utils/flagCountry.d.ts +1 -0
  266. package/src/utils/flagCountry.js +1 -0
  267. package/src/utils/function.d.ts +4 -0
  268. package/src/utils/function.js +19 -0
  269. package/src/utils/math.d.ts +16 -0
  270. package/src/utils/math.js +47 -0
  271. package/src/utils/nullish.d.ts +10 -0
  272. package/src/utils/nullish.js +8 -0
  273. package/src/utils/object.d.ts +2 -0
  274. package/src/utils/object.js +7 -0
  275. package/src/utils/popper.d.ts +3 -0
  276. package/src/utils/popper.js +30 -0
  277. package/src/utils/rifm.d.ts +14 -0
  278. package/src/utils/rifm.js +53 -0
  279. package/src/utils/string.d.ts +4 -0
  280. package/src/utils/string.js +233 -0
  281. package/src/utils/timer.d.ts +11 -0
  282. package/src/utils/timer.js +46 -0
  283. package/src/utils/types.d.ts +8 -0
  284. package/src/utils/types.js +1 -0
  285. package/src/utils/userAgent.d.ts +4 -0
  286. package/src/utils/userAgent.js +9 -0
  287. package/src/utils/viewport.d.ts +1 -0
  288. package/src/utils/viewport.js +12 -0
@@ -0,0 +1,398 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useLocation } from "@swan-io/chicane";
3
+ import { Box } from "@swan-io/lake/src/components/Box";
4
+ import { FocusTrap } from "@swan-io/lake/src/components/FocusTrap";
5
+ import { Icon } from "@swan-io/lake/src/components/Icon";
6
+ import { LakeText } from "@swan-io/lake/src/components/LakeText";
7
+ import { Link } from "@swan-io/lake/src/components/Link";
8
+ import { PressableText } from "@swan-io/lake/src/components/Pressable";
9
+ import { Space } from "@swan-io/lake/src/components/Space";
10
+ import { TransitionView } from "@swan-io/lake/src/components/TransitionView";
11
+ import { animations, backgroundColor, colors, negativeSpacings, radii, shadows, spacings, texts, } from "@swan-io/lake/src/constants/design";
12
+ import { useHover } from "@swan-io/lake/src/hooks/useHover";
13
+ import { useMergeRefs } from "@swan-io/lake/src/hooks/useMergeRefs";
14
+ import { isNotNullish, isNullish } from "@swan-io/lake/src/utils/nullish";
15
+ import { forwardRef, Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState, } from "react";
16
+ import { StyleSheet, Text, View } from "react-native";
17
+ import { match, P } from "ts-pattern";
18
+ import { noop } from "../utils/function";
19
+ const styles = StyleSheet.create({
20
+ container: {
21
+ borderBottomWidth: 1,
22
+ borderBottomColor: colors.gray[100],
23
+ zIndex: 10,
24
+ },
25
+ link: {
26
+ ...texts.medium,
27
+ position: "relative",
28
+ color: colors.gray[700],
29
+ height: 40,
30
+ whiteSpace: "nowrap",
31
+ display: "flex",
32
+ flexDirection: "row",
33
+ alignItems: "center",
34
+ },
35
+ activeLink: {
36
+ color: colors.current.primary,
37
+ boxShadow: `inset 0 -2px ${colors.gray[700]}`,
38
+ },
39
+ hoveredLink: {
40
+ boxShadow: `inset 0 -2px ${colors.gray[700]}`,
41
+ },
42
+ underline: {
43
+ position: "absolute",
44
+ bottom: 0,
45
+ height: 2,
46
+ width: 1,
47
+ backgroundColor: colors.current.primary,
48
+ },
49
+ animatedUnderline: {
50
+ transformOrigin: "0 0",
51
+ transition: "200ms ease-in-out transform",
52
+ },
53
+ placeholder: {
54
+ position: "absolute",
55
+ top: 0,
56
+ left: 0,
57
+ right: 0,
58
+ visibility: "hidden",
59
+ flexDirection: "row",
60
+ alignItems: "flex-end",
61
+ overflow: "hidden",
62
+ },
63
+ count: {
64
+ ...texts.smallRegular,
65
+ color: colors.current.primary,
66
+ backgroundColor: colors.current[50],
67
+ borderColor: colors.current[100],
68
+ borderWidth: 1,
69
+ borderRadius: radii[4],
70
+ paddingHorizontal: spacings[4],
71
+ minWidth: spacings[24],
72
+ display: "inline-block",
73
+ textAlign: "center",
74
+ },
75
+ dropdownHandleContainer: {
76
+ alignItems: "center",
77
+ justifyContent: "center",
78
+ alignSelf: "stretch",
79
+ },
80
+ dropdownPlacement: {
81
+ position: "absolute",
82
+ right: 0,
83
+ top: "100%",
84
+ },
85
+ dropdown: {
86
+ position: "absolute",
87
+ right: 0,
88
+ top: "100%",
89
+ backgroundColor: backgroundColor.accented,
90
+ borderRadius: radii[8],
91
+ boxShadow: shadows.modal,
92
+ paddingVertical: spacings[8],
93
+ },
94
+ dropdownLink: {
95
+ ...texts.regular,
96
+ paddingHorizontal: spacings[16],
97
+ paddingVertical: spacings[8],
98
+ whiteSpace: "nowrap",
99
+ },
100
+ dropdownLinkTextHovered: {
101
+ backgroundColor: colors.gray[50],
102
+ },
103
+ dropdownLinkTextActive: {
104
+ boxShadow: `inset 3px 0 ${colors.current.primary}`,
105
+ color: colors.current.primary,
106
+ },
107
+ separator: {
108
+ position: "absolute",
109
+ top: 0,
110
+ left: negativeSpacings[16],
111
+ bottom: 0,
112
+ width: 1,
113
+ backgroundColor: colors.gray[100],
114
+ },
115
+ });
116
+ const Dropdown = ({ tabs, onHoverStart, onHoverEnd, onLinkFocus, onLinkBlur, onLinkPress, }) => {
117
+ const containerRef = useRef(null);
118
+ useHover(containerRef, {
119
+ onHoverStart,
120
+ onHoverEnd,
121
+ });
122
+ return (_jsx(View, { accessibilityRole: "menu", style: styles.dropdown, ref: containerRef, children: tabs.map(({ url, label }) => {
123
+ return (_jsx(Link, { to: url, onFocus: onLinkFocus, onBlur: onLinkBlur, onPress: onLinkPress, accessibilityRole: "menuitem", ariaCurrentValue: "location", style: ({ active, hovered }) => [
124
+ styles.dropdownLink,
125
+ active && styles.dropdownLinkTextActive,
126
+ hovered && styles.dropdownLinkTextHovered,
127
+ ], children: label }, url));
128
+ }) }));
129
+ };
130
+ const SHOULD_AUTOFOCUS = new Set(["ForcedOpen", "OpenFromFocus"]);
131
+ const SHOULD_OPEN = new Set(["Open", "ForcedOpen", "OpenFromFocus"]);
132
+ const SHOULD_LOCK_FOCUS = new Set(["ForcedOpen"]);
133
+ const DropdownItems = forwardRef(({ tabs, otherLabel, currentUrl }, ref) => {
134
+ const [openingStatus, dispatch] = useReducer((state, action) => {
135
+ const input = [action, state];
136
+ return match(input)
137
+ .with(["ForceToggle", "Closed"], ["ForceToggle", "Open"], ["ForceToggle", "ForcedClosed"], () => "ForcedOpen")
138
+ .with(["ForceToggle", "OpenFromFocus"], ["ForceToggle", "ForcedOpen"], () => "ForcedClosed")
139
+ .with(["ForceClose", P.any], () => "ForcedClosed")
140
+ .with(["FocusHandle", "ForcedClosed"], () => "Closed")
141
+ .with(["Open", "ForcedOpen"], ["FocusHandle", "ForcedOpen"], ["Close", "ForcedOpen"], () => "ForcedOpen")
142
+ .with(["Open", P.any], () => "Open")
143
+ .with(["FocusHandle", P.any], () => "OpenFromFocus")
144
+ .with(["Close", P.any], () => "Closed")
145
+ .exhaustive();
146
+ }, "Closed");
147
+ const timeoutRef = useRef(undefined);
148
+ const handleRef = useRef(null);
149
+ const containerRef = useRef(null);
150
+ const lastFocusTimeout = useRef(null);
151
+ const { onHandleFocus, onLinkFocus, onAnyBlur, onHoverStart, onHoverEnd, onPress, onPressOutside, onEscapeKey, } = useMemo(() => ({
152
+ onHandleFocus: (event) => {
153
+ if (isNullish(containerRef.current)) {
154
+ return;
155
+ }
156
+ lastFocusTimeout.current = Date.now();
157
+ const container = containerRef.current;
158
+ const focusEvent = event;
159
+ // Don't reopen if leaving
160
+ if (!container.contains(focusEvent.relatedTarget)) {
161
+ if (isNotNullish(timeoutRef.current)) {
162
+ clearTimeout(timeoutRef.current);
163
+ }
164
+ dispatch("FocusHandle");
165
+ }
166
+ },
167
+ onLinkFocus: () => {
168
+ if (isNotNullish(timeoutRef.current)) {
169
+ clearTimeout(timeoutRef.current);
170
+ }
171
+ dispatch("Open");
172
+ },
173
+ onAnyBlur: () => {
174
+ if (isNotNullish(timeoutRef.current)) {
175
+ clearTimeout(timeoutRef.current);
176
+ }
177
+ timeoutRef.current = window.setTimeout(() => {
178
+ dispatch("Close");
179
+ }, 300);
180
+ },
181
+ onHoverStart: () => {
182
+ if (isNotNullish(timeoutRef.current)) {
183
+ clearTimeout(timeoutRef.current);
184
+ }
185
+ dispatch("Open");
186
+ },
187
+ onHoverEnd: () => {
188
+ if (isNotNullish(timeoutRef.current)) {
189
+ clearTimeout(timeoutRef.current);
190
+ }
191
+ timeoutRef.current = window.setTimeout(() => {
192
+ dispatch("Close");
193
+ }, 300);
194
+ },
195
+ onPress: () => {
196
+ if (lastFocusTimeout.current != null && Date.now() - lastFocusTimeout.current < 32) {
197
+ return;
198
+ }
199
+ if (isNotNullish(timeoutRef.current)) {
200
+ clearTimeout(timeoutRef.current);
201
+ }
202
+ dispatch("ForceToggle");
203
+ },
204
+ onPressOutside: (event) => {
205
+ if (isNotNullish(handleRef.current)) {
206
+ const handle = handleRef.current;
207
+ if (handle.contains(event.target)) {
208
+ return;
209
+ }
210
+ }
211
+ if (isNotNullish(timeoutRef.current)) {
212
+ clearTimeout(timeoutRef.current);
213
+ }
214
+ // Only force closing in case the focus comes directly to the handle
215
+ // Then put it back to a regular closed state
216
+ dispatch("ForceClose");
217
+ timeoutRef.current = window.setTimeout(() => {
218
+ dispatch("Close");
219
+ }, 300);
220
+ },
221
+ onEscapeKey: () => {
222
+ if (isNotNullish(timeoutRef.current)) {
223
+ clearTimeout(timeoutRef.current);
224
+ }
225
+ dispatch("ForceClose");
226
+ timeoutRef.current = window.setTimeout(() => {
227
+ dispatch("Close");
228
+ }, 300);
229
+ },
230
+ }), []);
231
+ useEffect(() => {
232
+ return () => {
233
+ if (isNotNullish(timeoutRef.current)) {
234
+ clearTimeout(timeoutRef.current);
235
+ }
236
+ };
237
+ }, []);
238
+ const shouldOpen = SHOULD_OPEN.has(openingStatus);
239
+ const shouldAutoFocus = SHOULD_AUTOFOCUS.has(openingStatus);
240
+ const shouldLockFocus = SHOULD_LOCK_FOCUS.has(openingStatus);
241
+ useHover(handleRef, {
242
+ onHoverStart,
243
+ onHoverEnd,
244
+ });
245
+ const mergedRef = useMergeRefs(containerRef, ref);
246
+ const activeTab = tabs.find(({ url }) => url === currentUrl);
247
+ return (_jsxs(View, { style: styles.dropdownHandleContainer, ref: mergedRef, children: [_jsxs(PressableText, { ref: handleRef, accessibilityRole: "button", accessibilityExpanded: shouldOpen, accessibilityHasPopup: "true", onFocus: onHandleFocus, onBlur: onAnyBlur, onPress: onPress, style: ({ hovered }) => [
248
+ styles.link,
249
+ isNotNullish(activeTab) ? styles.activeLink : hovered ? styles.hoveredLink : null,
250
+ ], children: [_jsx(Text, { children: otherLabel }), _jsx(Space, { width: 8 }), _jsx(Text, { style: styles.count, children: tabs.length }), _jsx(Space, { width: 4 }), _jsx(Icon, { name: "chevron-down-filled", size: 12 })] }), _jsx(TransitionView, { ...animations.fadeAndSlideInFromBottom, style: styles.dropdownPlacement, children: shouldOpen ? (_jsx(FocusTrap, { autoFocus: shouldAutoFocus, focusLock: shouldLockFocus, returnFocus: shouldLockFocus, onClickOutside: onPressOutside, onEscapeKey: shouldLockFocus ? onEscapeKey : undefined, children: _jsx(Dropdown, { tabs: tabs, onHoverStart: onHoverStart, onHoverEnd: onHoverEnd, onLinkFocus: onLinkFocus, onLinkBlur: onAnyBlur, onLinkPress: onEscapeKey }) })) : null })] }));
251
+ });
252
+ export const TabView = ({ tabs, otherLabel, hideIfSingleItem = true }) => {
253
+ const containerRef = useRef(null);
254
+ const placeholderRef = useRef(null);
255
+ const otherPlaceholderRef = useRef(null);
256
+ const linksRefs = useRef({});
257
+ const placeholderLinkRef = useRef({});
258
+ const [{ left, width }, setUnderlinePosition] = useState({ left: 0, width: 0 });
259
+ const [hasRendered, setHasRendered] = useState(false);
260
+ const [[kept, collapsed], setKeptCollapsed] = useState([[], []]);
261
+ const location = useLocation();
262
+ const { path } = location;
263
+ const currentLocationURL = location.toString();
264
+ useEffect(() => {
265
+ if (isNotNullish(linksRefs.current)) {
266
+ const values = Object.entries(linksRefs.current);
267
+ const container = containerRef.current;
268
+ for (const [link, node] of values) {
269
+ if ("/" + path.join("/") === link && isNotNullish(node) && isNotNullish(container)) {
270
+ node.measureLayout(container, (left, _, width) => {
271
+ setUnderlinePosition({ left, width });
272
+ }, noop);
273
+ return;
274
+ }
275
+ }
276
+ }
277
+ setUnderlinePosition({ left: 0, width: 0 });
278
+ }, [path, kept, collapsed]);
279
+ useEffect(() => {
280
+ setHasRendered(width > 0);
281
+ }, [width]);
282
+ const reajustLayout = useCallback(({ width }) => {
283
+ const items = tabs.map(tab => {
284
+ if (placeholderLinkRef.current) {
285
+ const ref = placeholderLinkRef.current[tab.url];
286
+ if (isNotNullish(ref)) {
287
+ const element = ref;
288
+ const width = element.getBoundingClientRect().width;
289
+ return { tab, width: width + 32 };
290
+ }
291
+ else {
292
+ return { tab, width: 0 };
293
+ }
294
+ }
295
+ else {
296
+ return { tab, width: 0 };
297
+ }
298
+ });
299
+ const kept = [];
300
+ const collapsed = [];
301
+ let cummulatedWidth = 0;
302
+ items.forEach(item => {
303
+ cummulatedWidth += item.width;
304
+ if (cummulatedWidth < width) {
305
+ kept.push({ ...item.tab, width: item.width });
306
+ }
307
+ else {
308
+ if (currentLocationURL.startsWith(item.tab.url)) {
309
+ while (kept.length !== 0 &&
310
+ kept.reduce((acc, item) => acc + item.width, 0) + (item.width + 16) >= width) {
311
+ const last = kept.pop();
312
+ if (isNotNullish(last)) {
313
+ collapsed.unshift(last);
314
+ cummulatedWidth -= last.width;
315
+ }
316
+ }
317
+ kept.push({ ...item.tab, width: item.width });
318
+ }
319
+ else {
320
+ collapsed.push({ ...item.tab, width: item.width });
321
+ }
322
+ }
323
+ });
324
+ const otherLabelRef = otherPlaceholderRef.current;
325
+ let otherLabelWidth = 100;
326
+ if (isNotNullish(otherLabelRef)) {
327
+ const otherLabel = otherLabelRef;
328
+ otherLabelWidth = otherLabel.getBoundingClientRect().width;
329
+ }
330
+ const activeInKeptIndex = kept.findIndex(item => currentLocationURL.startsWith(item.url));
331
+ if (activeInKeptIndex !== -1) {
332
+ const activeInKept = kept[activeInKeptIndex];
333
+ const activeInKeptWidth = activeInKept?.width ?? 0;
334
+ const restInKept = [
335
+ ...kept.slice(0, activeInKeptIndex),
336
+ ...kept.slice(activeInKeptIndex + 1),
337
+ ];
338
+ while (restInKept.length !== 0 &&
339
+ restInKept.reduce((acc, item) => acc + item.width, 0) +
340
+ activeInKeptWidth +
341
+ (collapsed.length >= 1 ? otherLabelWidth : 0) >=
342
+ width) {
343
+ const last = restInKept.pop();
344
+ if (isNotNullish(last)) {
345
+ collapsed.unshift(last);
346
+ }
347
+ }
348
+ const finalKept = [
349
+ ...restInKept.slice(0, activeInKeptIndex),
350
+ ...(activeInKept != null ? [activeInKept] : []),
351
+ ...restInKept.slice(activeInKeptIndex),
352
+ ];
353
+ setKeptCollapsed([finalKept, collapsed]);
354
+ }
355
+ else {
356
+ setKeptCollapsed([kept, collapsed]);
357
+ }
358
+ }, [tabs, currentLocationURL]);
359
+ const onLayout = useCallback(({ target, nativeEvent: { layout: { width }, }, }) => {
360
+ reajustLayout({ container: target, width });
361
+ }, [reajustLayout]);
362
+ useLayoutEffect(() => {
363
+ const ref = placeholderRef.current;
364
+ if (ref) {
365
+ const element = ref;
366
+ const width = element.getBoundingClientRect().width;
367
+ reajustLayout({ container: element, width });
368
+ }
369
+ }, [reajustLayout]);
370
+ if (tabs.length <= 1 && hideIfSingleItem) {
371
+ return null;
372
+ }
373
+ return (_jsxs(Box, { alignItems: "center", direction: "row", accessibilityRole: "tablist", ref: containerRef, style: styles.container, children: [_jsxs(View, { style: styles.placeholder, accessibilityHidden: true, ref: placeholderRef, pointerEvents: "none", onLayout: onLayout, children: [tabs.map(({ label, url, icon, count }) => (_jsxs(Fragment, { children: [_jsxs(Link, { ref: ref => {
374
+ if (placeholderLinkRef.current) {
375
+ placeholderLinkRef.current[url] = ref;
376
+ }
377
+ }, to: url, style: ({ active, hovered }) => [
378
+ styles.link,
379
+ active ? styles.activeLink : hovered ? styles.hoveredLink : null,
380
+ ], children: [isNotNullish(icon) && (_jsxs(_Fragment, { children: [_jsx(Icon, { name: icon, size: 16, color: "currentColor" }), _jsx(Space, { width: 8 })] })), _jsx(Text, { children: label }), count != null ? (_jsxs(_Fragment, { children: [_jsx(Space, { width: 8 }), _jsx(Text, { style: styles.count, children: count })] })) : null] }), _jsx(Space, { width: 32 })] }, url))), _jsxs(LakeText, { ref: otherPlaceholderRef, style: styles.link, children: [_jsx(Text, { children: otherLabel }), _jsx(Space, { width: 8 }), _jsx(Text, { style: styles.count, children: tabs.length }), _jsx(Space, { width: 4 }), _jsx(Icon, { name: "chevron-down-filled", size: 12 })] })] }), kept.map(({ label, url, icon, withSeparator, count }) => (_jsxs(Fragment, { children: [_jsxs(Link, { accessibilityRole: "tab", ref: ref => {
381
+ if (linksRefs.current) {
382
+ linksRefs.current[url] = ref;
383
+ }
384
+ }, to: url, style: ({ active, hovered }) => [
385
+ styles.link,
386
+ active ? styles.activeLink : hovered ? styles.hoveredLink : null,
387
+ ], children: [withSeparator === true && _jsx(View, { style: styles.separator, accessibilityRole: "none" }), isNotNullish(icon) && (_jsxs(_Fragment, { children: [_jsx(Icon, { name: icon, size: 16, color: "currentColor" }), _jsx(Space, { width: 8 })] })), _jsx(Text, { children: label }), count != null ? (_jsxs(_Fragment, { children: [_jsx(Space, { width: 8 }), _jsx(Text, { style: styles.count, children: count })] })) : null] }), _jsx(Space, { width: 32 })] }, url))), collapsed.length > 0 ? (_jsx(DropdownItems, { ref: ref => {
388
+ collapsed.forEach(item => {
389
+ if (linksRefs.current) {
390
+ linksRefs.current[item.url] = ref;
391
+ }
392
+ });
393
+ }, tabs: collapsed, currentUrl: currentLocationURL, otherLabel: otherLabel })) : null, hasRendered && (_jsx(View, { style: [
394
+ styles.underline,
395
+ styles.animatedUnderline,
396
+ { transform: [{ translateX: left }, { scaleX: width }] },
397
+ ] }))] }));
398
+ };
@@ -0,0 +1,34 @@
1
+ import { ComponentProps, ComponentType, ReactElement, ReactNode } from "react";
2
+ import { FlatList, StyleProp, ViewStyle } from "react-native";
3
+ /**
4
+ * `fixed` set the column width in px
5
+ * `percentage` set the column with in remaining percentage (by using flex-basis)
6
+ */
7
+ type ColumnWidth = {
8
+ type: "fixed";
9
+ value: number;
10
+ } | {
11
+ type: "remainingPercent";
12
+ value: number;
13
+ };
14
+ export type TableColumn<T> = {
15
+ key: string;
16
+ width: ColumnWidth;
17
+ label: string;
18
+ render: (item: T) => ReactNode;
19
+ };
20
+ type Props<T> = {
21
+ keyExtractor?: (item: T, index: number) => string;
22
+ columns: TableColumn<T>[];
23
+ data: T[];
24
+ hideColumns?: boolean;
25
+ ListEmptyComponent?: ComponentType<unknown> | ReactElement | null;
26
+ ListFooterComponent?: ComponentType<unknown> | ReactElement | null;
27
+ ListHeaderComponent?: ComponentType<unknown> | ReactElement | null;
28
+ onPressLine?: (item: T) => void;
29
+ isDisabledLine?: (item: T) => boolean;
30
+ onEndReached?: ComponentProps<typeof FlatList>["onEndReached"];
31
+ contentContainerStyle?: StyleProp<ViewStyle>;
32
+ };
33
+ export declare function Table<T>({ keyExtractor, columns, data, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, onPressLine, isDisabledLine, onEndReached, contentContainerStyle, hideColumns, }: Props<T>): JSX.Element;
34
+ export {};
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment, useEffect, } from "react";
3
+ import { FlatList, Pressable, StyleSheet, Text, View } from "react-native";
4
+ import { match } from "ts-pattern";
5
+ import { colors } from "../constants/colors";
6
+ import { commonStyles } from "../constants/commonStyles";
7
+ import { typography } from "../constants/typography";
8
+ import { Box } from "./Box";
9
+ import { Separator } from "./Separator";
10
+ import { Space } from "./Space";
11
+ const styles = StyleSheet.create({
12
+ content: {
13
+ flexGrow: 1,
14
+ },
15
+ header: {
16
+ height: 44,
17
+ paddingHorizontal: 16,
18
+ },
19
+ head: {
20
+ ...typography.bodySmall,
21
+ fontWeight: typography.fontWeights.demi,
22
+ color: colors.gray[100],
23
+ },
24
+ row: {
25
+ flexDirection: "row",
26
+ alignItems: "center",
27
+ height: 56,
28
+ paddingHorizontal: 16,
29
+ transitionDuration: "300ms",
30
+ transitionProperty: "background-color",
31
+ },
32
+ rowHover: {
33
+ backgroundColor: colors.gray[3],
34
+ },
35
+ rowPressed: {
36
+ opacity: 0.75,
37
+ },
38
+ text: {
39
+ ...typography.bodySmall,
40
+ color: colors.gray[80],
41
+ },
42
+ });
43
+ const getColumnStyle = (width) => {
44
+ return match(width.type)
45
+ .with("remainingPercent", () => ({
46
+ flexBasis: `${width.value}%`,
47
+ flexShrink: 1,
48
+ }))
49
+ .with("fixed", () => ({
50
+ width: width.value,
51
+ flexShrink: 0,
52
+ }))
53
+ .exhaustive();
54
+ };
55
+ const isText = (node) => ["string", "number"].includes(typeof node);
56
+ export function Table({ keyExtractor, columns, data, ListEmptyComponent, ListFooterComponent, ListHeaderComponent, onPressLine, isDisabledLine, onEndReached, contentContainerStyle, hideColumns = false, }) {
57
+ // Add width checker which run only during development
58
+ if (process.env.NODE_ENV === "development") {
59
+ // We use useEffect to avoid spaming development console with warning message
60
+ // eslint-disable-next-line react-hooks/rules-of-hooks
61
+ useEffect(() => {
62
+ const columnsInPercent = columns.filter(({ width }) => width.type === "remainingPercent");
63
+ const percentWidth = columnsInPercent.reduce((acc, { width }) => acc + width.value, 0);
64
+ if (process.env.NODE_ENV === "development" && percentWidth !== 100) {
65
+ console.warn(`Invalid Table width: total remaining width is ${percentWidth}, please check columns config where 'width.type' is 'remainingPercent'`);
66
+ }
67
+ }, [columns]);
68
+ }
69
+ return (_jsxs(View, { style: commonStyles.fill, children: [!hideColumns && (_jsx(Box, { direction: "row", alignItems: "center", style: styles.header, children: columns.map(({ key, width, label }, index) => (_jsxs(Fragment, { children: [index > 0 && _jsx(Space, { width: 4 }), _jsx(Text, { numberOfLines: 1, style: [styles.head, getColumnStyle(width)], children: label })] }, key))) })), _jsx(FlatList, { keyExtractor: keyExtractor, contentContainerStyle: StyleSheet.flatten([styles.content, contentContainerStyle]), accessibilityRole: "list", data: data, ListHeaderComponent: ListHeaderComponent, ListFooterComponent: ListFooterComponent, onEndReached: onEndReached, onEndReachedThreshold: 0.5, ItemSeparatorComponent: Separator, renderItem: ({ item }) => {
70
+ return (_jsx(Pressable, { style: ({ hovered, pressed }) => [
71
+ styles.row,
72
+ hovered && styles.rowHover,
73
+ pressed && styles.rowPressed,
74
+ ], disabled: !onPressLine || isDisabledLine?.(item) === true, onPress: () => onPressLine?.(item), children: columns.map(({ key, width, render }, index) => {
75
+ const content = render(item);
76
+ return (_jsxs(Fragment, { children: [index > 0 && _jsx(Space, { width: 4 }), _jsx(View, { style: getColumnStyle(width), children: isText(content) ? (_jsx(Text, { numberOfLines: 1, style: styles.text, children: content })) : (content) })] }, key));
77
+ }) }));
78
+ }, ListEmptyComponent: ListEmptyComponent })] }));
79
+ }
@@ -0,0 +1,17 @@
1
+ import { ReactElement, ReactFragment, ReactText } from "react";
2
+ import { StyleProp, ViewStyle } from "react-native";
3
+ import { ColorVariants } from "../constants/design";
4
+ import { IconName } from "./Icon";
5
+ type Props = {
6
+ children?: ReactElement | ReactText | ReactFragment;
7
+ label?: string;
8
+ icon?: IconName;
9
+ iconSize?: number;
10
+ size?: "small" | "large";
11
+ color?: ColorVariants;
12
+ onPressRemove?: () => void;
13
+ style?: StyleProp<ViewStyle>;
14
+ accessibilityLabel?: string;
15
+ };
16
+ export declare const Tag: ({ children, label, color, size, icon, iconSize, accessibilityLabel, onPressRemove, style, }: Props) => JSX.Element;
17
+ export {};
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Pressable, StyleSheet, Text } from "react-native";
3
+ import { colors, texts } from "../constants/design";
4
+ import { isNotNullish, isNotNullishOrEmpty, isNullish } from "../utils/nullish";
5
+ import { Box } from "./Box";
6
+ import { Icon } from "./Icon";
7
+ import { Space } from "./Space";
8
+ const styles = StyleSheet.create({
9
+ base: {
10
+ borderRadius: 4,
11
+ borderWidth: 1,
12
+ height: 28,
13
+ overflow: "hidden",
14
+ },
15
+ onlyIcon: {
16
+ height: 28,
17
+ width: 28,
18
+ padding: 0,
19
+ },
20
+ larger: {
21
+ paddingHorizontal: 4,
22
+ height: 40,
23
+ },
24
+ label: {
25
+ borderTopRightRadius: 0,
26
+ borderBottomRightRadius: 0,
27
+ borderRightWidth: 0,
28
+ },
29
+ text: {
30
+ ...texts.smallMedium,
31
+ display: "flex",
32
+ alignItems: "center",
33
+ justifyContent: "center",
34
+ paddingHorizontal: 8,
35
+ },
36
+ dismiss: {
37
+ justifyContent: "center",
38
+ height: "100%",
39
+ paddingHorizontal: 8,
40
+ borderLeftWidth: 1,
41
+ },
42
+ });
43
+ export const Tag = ({ children, label, color = "gray", size = "small", icon, iconSize = 16, accessibilityLabel, onPressRemove, style, }) => {
44
+ const hasRemoveButton = isNotNullish(onPressRemove);
45
+ const hasLabel = isNotNullishOrEmpty(label);
46
+ const hasOnlyIcon = isNullish(children) && isNotNullish(icon);
47
+ const { primary, ...variant } = colors[color];
48
+ const tint50 = variant[50];
49
+ const tint100 = variant[100];
50
+ const tint200 = variant[200];
51
+ return (_jsxs(Box, { direction: "row", children: [hasLabel && (_jsx(Box, { alignItems: "center", direction: "row", style: [
52
+ styles.base,
53
+ styles.label,
54
+ size === "large" && styles.larger,
55
+ { backgroundColor: tint100, borderColor: tint200 },
56
+ ], children: _jsx(Text, { numberOfLines: 1, selectable: false, style: [styles.text, { color: primary }], children: label }) })), _jsxs(Box, { alignItems: "center", direction: "row", accessibilityLabel: accessibilityLabel, style: [
57
+ styles.base,
58
+ size === "large" && styles.larger,
59
+ hasOnlyIcon && styles.onlyIcon,
60
+ {
61
+ backgroundColor: tint50,
62
+ borderColor: tint200,
63
+ ...(hasLabel && {
64
+ borderLeftWidth: 0,
65
+ borderTopLeftRadius: 0,
66
+ borderBottomLeftRadius: 0,
67
+ }),
68
+ },
69
+ style,
70
+ ], children: [_jsxs(Text, { numberOfLines: 1, style: [styles.text, hasOnlyIcon && styles.onlyIcon, { color: primary }], children: [icon && (_jsxs(_Fragment, { children: [_jsx(Icon, { name: icon, color: primary, size: iconSize }), isNotNullish(children) && _jsx(Space, { width: 8 })] })), children] }), hasRemoveButton && (_jsx(Pressable, { accessibilityRole: "button", onPress: onPressRemove, style: ({ hovered, pressed }) => [
71
+ styles.dismiss,
72
+ { color: primary, borderColor: tint100 },
73
+ hovered && { backgroundColor: tint100 },
74
+ pressed && { backgroundColor: tint200 },
75
+ ], children: _jsx(Icon, { name: "dismiss-regular", color: primary, size: 10 }) }))] })] }));
76
+ };
@@ -0,0 +1,34 @@
1
+ import { ReactNode } from "react";
2
+ import { StyleProp, ViewStyle } from "react-native";
3
+ import { Spacings } from "../constants/design";
4
+ type Props = {
5
+ icon?: ReactNode;
6
+ title?: ReactNode;
7
+ description?: ReactNode;
8
+ headerEnd?: ReactNode;
9
+ paddingVertical?: Spacings;
10
+ paddingHorizontal?: Spacings;
11
+ children?: ReactNode;
12
+ footer?: ReactNode;
13
+ numberOfLines?: number;
14
+ flexBasis?: string;
15
+ flexGrow?: number;
16
+ flexShrink?: number;
17
+ hovered?: boolean;
18
+ disabled?: boolean;
19
+ selected?: boolean;
20
+ style?: StyleProp<ViewStyle>;
21
+ };
22
+ export declare const Tile: ({ icon, title, description, headerEnd, footer, flexBasis, children, numberOfLines, paddingVertical, paddingHorizontal, hovered, flexGrow, flexShrink, disabled, selected, style, }: Props) => JSX.Element;
23
+ export declare const TileFullWidthContent: ({ children, flexGrow, fitToBottom, }: {
24
+ children: ReactNode;
25
+ flexGrow?: number | undefined;
26
+ fitToBottom?: boolean | undefined;
27
+ }) => JSX.Element;
28
+ type TileGridProps = {
29
+ breakpoint?: number;
30
+ children: ReactNode;
31
+ };
32
+ export declare const TileGrid: ({ children, breakpoint }: TileGridProps) => JSX.Element;
33
+ export declare const TileRows: ({ children, breakpoint }: TileGridProps) => JSX.Element;
34
+ export {};