@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,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, memo, useId } from "react";
3
+ import { StyleSheet, View } from "react-native";
4
+ import { colors } from "../constants/colors";
5
+ import { typography } from "../constants/typography";
6
+ import { isNotNullish } from "../utils/nullish";
7
+ import { InputError } from "./InputError";
8
+ import { Label } from "./Label";
9
+ import { PressableTextInput } from "./Pressable";
10
+ import { Space } from "./Space";
11
+ const styles = StyleSheet.create({
12
+ base: {
13
+ ...typography.bodyLarge,
14
+ backgroundColor: colors.white,
15
+ borderColor: colors.gray[10],
16
+ borderRadius: 4,
17
+ borderWidth: 1,
18
+ flexGrow: 1,
19
+ flexShrink: 1,
20
+ maxWidth: "100%",
21
+ minHeight: 128,
22
+ outlineStyle: "none",
23
+ padding: 16,
24
+ placeholderTextColor: colors.gray[30],
25
+ resize: "vertical",
26
+ transitionProperty: ["border-color", "box-shadow"],
27
+ transitionDuration: "150ms",
28
+ },
29
+ focused: {
30
+ borderColor: colors.gray[30],
31
+ shadowColor: colors.gray[100],
32
+ shadowOpacity: 0.12,
33
+ shadowOffset: { height: 0, width: 0 },
34
+ shadowRadius: 2,
35
+ },
36
+ hovered: {
37
+ shadowColor: colors.gray[100],
38
+ shadowOpacity: 0.06,
39
+ shadowOffset: { height: 4, width: 0 },
40
+ shadowRadius: 8,
41
+ },
42
+ errored: {
43
+ borderColor: colors.red[100],
44
+ paddingRight: 48,
45
+ },
46
+ });
47
+ export const MultilineInput = memo(forwardRef(({ disabled = false, error, label, onBlur, onSubmitEditing, onValueChange, placeholder, readOnly = false, value = "", }, forwardedRef) => {
48
+ const id = `input-${useId()}`;
49
+ return (_jsxs(View, { children: [_jsx(Label, { htmlFor: id, children: label }), _jsx(Space, { height: 8 }), _jsx(PressableTextInput, { nativeID: id, ref: forwardedRef, allowFontScaling: false, autoComplete: "off", editable: !readOnly && !disabled, multiline: true, onBlur: onBlur, onChangeText: onValueChange, onSubmitEditing: onSubmitEditing, placeholder: placeholder, value: value, style: ({ hovered, focused }) => [
50
+ styles.base,
51
+ focused ? styles.focused : hovered && styles.hovered,
52
+ isNotNullish(error) && styles.errored,
53
+ ] }), _jsx(InputError, { message: error })] }));
54
+ }));
55
+ MultilineInput.displayName = "MultilineInput";
@@ -0,0 +1,26 @@
1
+ import { ReactNode } from "react";
2
+ import { StyleProp, ViewStyle } from "react-native";
3
+ type Props<V, I extends {
4
+ value: V;
5
+ }> = {
6
+ value: V;
7
+ items: I[];
8
+ onValueChange: (item: V) => void;
9
+ renderItem: (item: I) => ReactNode | null;
10
+ renderValue?: (item: I) => ReactNode | null;
11
+ itemHeight?: number;
12
+ describedBy?: string;
13
+ size?: "large" | "small";
14
+ label?: string | (() => ReactNode);
15
+ info?: ReactNode;
16
+ disabled?: boolean;
17
+ style?: StyleProp<ViewStyle>;
18
+ pickerStyle?: StyleProp<ViewStyle>;
19
+ hideErrorMessage?: boolean;
20
+ };
21
+ export declare const Picker: (<V, I extends {
22
+ value: V;
23
+ }>(props: Props<V, I>) => JSX.Element | null) & {
24
+ displayName?: string | undefined;
25
+ };
26
+ export {};
@@ -0,0 +1,116 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo as reactMemo, useMemo, useRef } from "react";
3
+ import isEqual from "react-fast-compare";
4
+ import { FlatList, Pressable, StyleSheet, Text, View } from "react-native";
5
+ import { colors } from "../constants/colors";
6
+ import { commonStyles } from "../constants/commonStyles";
7
+ import { typography } from "../constants/typography";
8
+ import { useBoolean } from "../hooks/useBoolean";
9
+ import { Fill } from "./Fill";
10
+ import { Icon } from "./Icon";
11
+ import { InputError } from "./InputError";
12
+ import { Label } from "./Label";
13
+ import { Popover } from "./Popover";
14
+ import { Space } from "./Space";
15
+ const ELEMENT_HEIGHT = 48;
16
+ const styles = StyleSheet.create({
17
+ base: {
18
+ alignItems: "center",
19
+ backgroundColor: colors.white,
20
+ borderColor: colors.gray[10],
21
+ borderRadius: 4,
22
+ borderWidth: 1,
23
+ flexDirection: "row",
24
+ flexGrow: 1,
25
+ flexShrink: 1,
26
+ height: 48,
27
+ outlineStyle: "none",
28
+ paddingHorizontal: 16,
29
+ transitionDuration: "150ms",
30
+ transitionProperty: ["border-color", "box-shadow"],
31
+ },
32
+ small: {
33
+ height: 40,
34
+ },
35
+ focused: {
36
+ borderColor: colors.gray[20],
37
+ shadowColor: colors.gray[100],
38
+ shadowOpacity: 0.12,
39
+ shadowOffset: { height: 0, width: 0 },
40
+ shadowRadius: 2,
41
+ },
42
+ hovered: {
43
+ shadowColor: colors.gray[100],
44
+ shadowOpacity: 0.06,
45
+ shadowOffset: { height: 4, width: 0 },
46
+ shadowRadius: 8,
47
+ },
48
+ disabled: {
49
+ backgroundColor: colors.gray[3],
50
+ borderColor: colors.gray[3],
51
+ cursor: "not-allowed",
52
+ },
53
+ list: {
54
+ maxHeight: ELEMENT_HEIGHT * 4.5,
55
+ backgroundColor: colors.white,
56
+ borderRadius: 4,
57
+ shadowColor: colors.gray[100],
58
+ shadowOpacity: 0.12,
59
+ shadowOffset: { height: 6, width: 0 },
60
+ shadowRadius: 24,
61
+ },
62
+ item: {
63
+ alignItems: "center",
64
+ flexDirection: "row",
65
+ flexGrow: 1,
66
+ flexShrink: 1,
67
+ paddingHorizontal: 16,
68
+ paddingVertical: 0,
69
+ transitionProperty: "background-color",
70
+ transitionDuration: "200ms",
71
+ },
72
+ hoveredItem: {
73
+ backgroundColor: colors.gray[3],
74
+ },
75
+ pressedItem: {
76
+ backgroundColor: colors.gray[10],
77
+ },
78
+ itemText: {
79
+ ...typography.bodyLarge,
80
+ },
81
+ });
82
+ const isReactText = (node) => ["string", "number"].includes(typeof node);
83
+ const memo = reactMemo;
84
+ export const Picker = memo(({ value, items, onValueChange, renderItem, renderValue = renderItem, itemHeight = ELEMENT_HEIGHT, describedBy, size = "large", label = "", info = "", disabled = false, style, pickerStyle, hideErrorMessage = false, }) => {
85
+ const buttonRef = useRef(null);
86
+ const [visible, setVisible] = useBoolean(false);
87
+ const selectedItem = items.find(item => item.value === value);
88
+ const selectedRendered = selectedItem ? renderValue(selectedItem) : undefined;
89
+ const getItemLayout = useMemo(() => (data, index) => ({
90
+ length: itemHeight,
91
+ offset: itemHeight * index,
92
+ index,
93
+ }), [itemHeight]);
94
+ return (_jsxs(View, { style: style, children: [typeof label === "function"
95
+ ? label()
96
+ : label !== "" && (_jsxs(_Fragment, { children: [_jsx(Label, { children: label }), _jsx(Space, { height: 8 })] })), _jsxs(Pressable, { ref: buttonRef, accessibilityRole: "button", disabled: disabled, onPress: setVisible.toggle, style: ({ hovered, focused }) => [
97
+ styles.base,
98
+ size === "small" && styles.small,
99
+ pickerStyle,
100
+ focused || visible ? styles.focused : hovered && styles.hovered,
101
+ disabled && styles.disabled,
102
+ ], children: [selectedItem ? (_jsx(View, { style: commonStyles.fill, children: isReactText(selectedRendered) ? (_jsx(Text, { numberOfLines: 1, style: styles.itemText, children: selectedRendered })) : (selectedRendered) })) : (_jsx(Fill, {})), !disabled && (_jsxs(_Fragment, { children: [_jsx(Space, { height: 8 }), _jsx(Icon, { name: visible ? "chevron-up-filled" : "chevron-down-filled", color: colors.gray[30], size: 18 })] }))] }), info !== "" && (_jsxs(_Fragment, { children: [_jsx(Space, { height: 8 }), _jsx(View, { children: info })] })), !hideErrorMessage && _jsx(InputError, {}), _jsx(Popover, { referenceRef: buttonRef, matchReferenceWidth: true, describedBy: describedBy, visible: visible, onDismiss: setVisible.toggle, children: _jsx(FlatList, { getItemLayout: getItemLayout, accessibilityRole: "list", data: items, style: styles.list, keyExtractor: item => `option-${item.value}`, renderItem: ({ item }) => {
103
+ const selected = item.value === value;
104
+ const rendered = renderItem(item);
105
+ return (_jsxs(Pressable, { accessibilityRole: "listitem", accessibilitySelected: selected, style: ({ hovered, pressed }) => [
106
+ styles.item,
107
+ (hovered || selected) && styles.hoveredItem,
108
+ pressed && styles.pressedItem,
109
+ { height: itemHeight },
110
+ ], onPress: () => {
111
+ onValueChange(item.value);
112
+ setVisible.toggle();
113
+ }, children: [isReactText(rendered) ? (_jsx(Text, { numberOfLines: 1, style: styles.itemText, children: rendered })) : (rendered), selected && (_jsxs(_Fragment, { children: [_jsx(Fill, { minWidth: 16 }), _jsx(Icon, { name: "checkmark-filled", color: colors.green[100], size: 20 })] }))] }));
114
+ } }) })] }));
115
+ }, isEqual);
116
+ Picker.displayName = "Picker";
@@ -0,0 +1,36 @@
1
+ import { ReactElement, ReactNode } from "react";
2
+ import { PressableStateCallbackType } from "react-native";
3
+ import { ColumnCellConfig, ColumnTitleConfig, LinkConfig } from "./FixedListView";
4
+ export type ColumnConfig<T, ExtraInfo> = {
5
+ id: string;
6
+ width: number | "grow";
7
+ title: string;
8
+ renderTitle: (props: ColumnTitleConfig<ExtraInfo>) => ReactNode;
9
+ renderCell: (props: ColumnCellConfig<T, ExtraInfo>) => ReactNode;
10
+ };
11
+ type Props<T, ExtraInfo> = {
12
+ data: T[];
13
+ keyExtractor: (item: T, index: number) => string;
14
+ highlightedRowId?: string;
15
+ headerHeight: number;
16
+ rowHeight: number;
17
+ groupHeaderHeight: number;
18
+ extraInfo: ExtraInfo;
19
+ columns: ColumnConfig<T, ExtraInfo>[];
20
+ smallColumns?: ColumnConfig<T, ExtraInfo>[];
21
+ onEndReached?: () => void;
22
+ onEndReachedThresholdPx?: number;
23
+ getRowLink?: (config: LinkConfig<T, ExtraInfo>) => ReactElement<{
24
+ children: (state: PressableStateCallbackType) => React.ReactNode;
25
+ }>;
26
+ renderEmptyList?: () => ReactNode;
27
+ groupBy?: (item: T) => string;
28
+ onActiveRowChange?: (element: HTMLElement) => void;
29
+ activeRowId?: string;
30
+ loading?: {
31
+ isLoading: boolean;
32
+ count: number;
33
+ };
34
+ };
35
+ export declare const PlainListView: <T, ExtraInfo>({ data: originalData, keyExtractor, rowHeight, groupHeaderHeight, headerHeight, columns, smallColumns, extraInfo, onEndReached, onEndReachedThresholdPx, getRowLink, activeRowId, renderEmptyList, onActiveRowChange, groupBy, loading, }: Props<T, ExtraInfo>) => JSX.Element;
36
+ export {};
@@ -0,0 +1,208 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { cloneElement, Fragment, useCallback, useEffect, useId, useMemo, useRef, useState, } from "react";
3
+ import { ScrollView, StyleSheet, View, } from "react-native";
4
+ import { backgroundColor, breakpoints, colors, spacings } from "../constants/design";
5
+ import { useHover } from "../hooks/useHover";
6
+ import { isNotNullish, isNullish } from "../utils/nullish";
7
+ import { PlainListViewPlaceholder, } from "./FixedListView";
8
+ import { LakeHeading } from "./LakeHeading";
9
+ import { ResponsiveContainer } from "./ResponsiveContainer";
10
+ const INHERIT = "inherit";
11
+ const styles = StyleSheet.create({
12
+ root: {
13
+ height: 1,
14
+ alignSelf: "stretch",
15
+ flexGrow: 1,
16
+ backgroundColor: backgroundColor.default,
17
+ },
18
+ container: {
19
+ height: 1,
20
+ alignSelf: "stretch",
21
+ flexGrow: 1,
22
+ },
23
+ contentContainer: {
24
+ flexDirection: "column",
25
+ alignItems: "stretch",
26
+ flexGrow: 1,
27
+ },
28
+ segment: {
29
+ flexDirection: "row",
30
+ alignItems: "stretch",
31
+ overflow: "hidden",
32
+ paddingHorizontal: spacings[8],
33
+ },
34
+ segmentLarge: {
35
+ paddingHorizontal: spacings[24],
36
+ },
37
+ row: {
38
+ boxShadow: `inset 0 -1px ${colors.gray[100]}`,
39
+ },
40
+ activeRow: {
41
+ backgroundColor: backgroundColor.accented,
42
+ },
43
+ hoveredRow: {
44
+ backgroundColor: backgroundColor.accented,
45
+ },
46
+ segmentHeaderCell: {
47
+ display: "flex",
48
+ flexDirection: "row",
49
+ alignItems: "center",
50
+ },
51
+ stickyHeader: {
52
+ position: "sticky",
53
+ top: 0,
54
+ backgroundColor: backgroundColor.default90Transparency,
55
+ backdropFilter: "blur(4px)",
56
+ zIndex: 10,
57
+ paddingHorizontal: spacings[24],
58
+ flexDirection: "row",
59
+ alignItems: "center",
60
+ },
61
+ stickyHeaderLarge: {
62
+ paddingHorizontal: spacings[40],
63
+ },
64
+ loadingPlaceholder: {
65
+ position: "absolute",
66
+ left: 0,
67
+ right: 0,
68
+ top: 0,
69
+ },
70
+ rowLink: {
71
+ color: INHERIT,
72
+ textDecorationLine: "none",
73
+ },
74
+ emptyListContainer: {
75
+ position: "absolute",
76
+ top: 0,
77
+ left: 0,
78
+ right: 0,
79
+ bottom: 0,
80
+ flexDirection: "column",
81
+ alignItems: "center",
82
+ justifyContent: "center",
83
+ padding: spacings[48],
84
+ backgroundColor: backgroundColor.default,
85
+ },
86
+ });
87
+ const ONE = 1;
88
+ const ZERO = 0;
89
+ const Row = ({ id, item, index, rowHeight, columns, extraInfo, isActive, isHovered, large, onMouseEnter, onMouseLeave, }) => {
90
+ const containerRef = useRef(null);
91
+ useHover(containerRef, {
92
+ onHoverStart: () => onMouseEnter(id),
93
+ onHoverEnd: () => onMouseLeave(),
94
+ });
95
+ return (_jsx(View, { ref: containerRef, style: [
96
+ styles.segment,
97
+ large && styles.segmentLarge,
98
+ styles.row,
99
+ isActive && styles.activeRow,
100
+ isHovered && styles.hoveredRow,
101
+ { minHeight: rowHeight },
102
+ ], children: columns.map(({ width, id: columnId, renderCell }) => (_jsx(View, { style: [
103
+ styles.segmentHeaderCell,
104
+ {
105
+ width: typeof width === "number" ? width : ONE,
106
+ flexGrow: width === "grow" ? ONE : ZERO,
107
+ },
108
+ ], nativeID: columnId, children: renderCell({ columnId, item, index, extraInfo, isHovered }) }, columnId))) }));
109
+ };
110
+ export const PlainListView = ({ data: originalData, keyExtractor, rowHeight, groupHeaderHeight, headerHeight, columns, smallColumns = columns, extraInfo, onEndReached, onEndReachedThresholdPx = 200, getRowLink, activeRowId, renderEmptyList, onActiveRowChange, groupBy, loading, }) => {
111
+ const viewId = useId();
112
+ const groups = useMemo(() => {
113
+ if (groupBy == null) {
114
+ return new Map([[null, originalData]]);
115
+ }
116
+ const map = new Map();
117
+ originalData.forEach(item => {
118
+ const key = groupBy(item);
119
+ map.set(key, [...(map.get(key) ?? []), item]);
120
+ });
121
+ return map;
122
+ }, [groupBy, originalData]);
123
+ const totalHeight = rowHeight * originalData.length + groups.size * groupHeaderHeight;
124
+ const isLoading = isNotNullish(loading) && loading.isLoading;
125
+ const hasEndReachedBeenCalled = useRef(false);
126
+ const lastKnownHeight = useRef(0);
127
+ const [hoveredRow, setHoveredRow] = useState(undefined);
128
+ const removeHoveredRow = useCallback(() => {
129
+ setHoveredRow(undefined);
130
+ }, []);
131
+ const onLayout = useCallback(({ nativeEvent: { layout: { height }, }, }) => {
132
+ lastKnownHeight.current = height;
133
+ if (isNotNullish(onEndReached) &&
134
+ !hasEndReachedBeenCalled.current &&
135
+ height >= totalHeight - onEndReachedThresholdPx) {
136
+ hasEndReachedBeenCalled.current = true;
137
+ onEndReached();
138
+ }
139
+ }, [onEndReached, onEndReachedThresholdPx, totalHeight]);
140
+ useEffect(() => {
141
+ if (isNotNullish(onEndReached) &&
142
+ !hasEndReachedBeenCalled.current &&
143
+ lastKnownHeight.current >= totalHeight - onEndReachedThresholdPx) {
144
+ hasEndReachedBeenCalled.current = true;
145
+ onEndReached();
146
+ return;
147
+ }
148
+ hasEndReachedBeenCalled.current = false;
149
+ }, [originalData, onEndReached, onEndReachedThresholdPx, totalHeight]);
150
+ const onScroll = useCallback(({ nativeEvent: { contentOffset: { y }, layoutMeasurement: { height }, contentSize: { height: contentHeight }, }, }) => {
151
+ lastKnownHeight.current = height;
152
+ if (isNotNullish(onEndReached) &&
153
+ !hasEndReachedBeenCalled.current &&
154
+ y + height >= contentHeight - onEndReachedThresholdPx) {
155
+ hasEndReachedBeenCalled.current = true;
156
+ onEndReached();
157
+ }
158
+ }, [onEndReached, onEndReachedThresholdPx]);
159
+ const createRowWrapper = useCallback(({ item, absoluteIndex, extraInfo, }) => {
160
+ const customLinkElement = getRowLink?.({ item, index: absoluteIndex, extraInfo });
161
+ return isNullish(customLinkElement) ? _jsx(View, {}) : customLinkElement;
162
+ }, [getRowLink]);
163
+ const activeItemRef = useRef(null);
164
+ useEffect(() => {
165
+ const ref = activeItemRef.current;
166
+ if (activeRowId != null && ref != null) {
167
+ const element = ref;
168
+ element.scrollIntoView({ behavior: "smooth", block: "nearest" });
169
+ onActiveRowChange?.(element);
170
+ }
171
+ }, [activeRowId, onActiveRowChange]);
172
+ return (_jsx(ResponsiveContainer, { style: styles.root, breakpoint: breakpoints.large, children: ({ large }) => {
173
+ const displayColumns = large ? columns : smallColumns;
174
+ return (_jsxs(_Fragment, { children: [large ? (_jsx(View, { style: [styles.segment, large && styles.segmentLarge], children: displayColumns.map(({ id, width, title, renderTitle }) => {
175
+ const columnId = `${viewId}_${id}`;
176
+ return (_jsx(View, { style: [
177
+ styles.segmentHeaderCell,
178
+ {
179
+ width: typeof width === "number" ? width : ONE,
180
+ flexGrow: width === "grow" ? ONE : ZERO,
181
+ height: headerHeight,
182
+ },
183
+ ], nativeID: columnId, children: renderTitle({ title, extraInfo, id }) }, columnId));
184
+ }) })) : null, _jsxs(ScrollView, { scrollEventThrottle: 32, style: styles.container, onLayout: onLayout, onScroll: onScroll, contentContainerStyle: [
185
+ styles.contentContainer,
186
+ {
187
+ minHeight: totalHeight + (isLoading ? loading.count * rowHeight : 0),
188
+ },
189
+ ], children: [Array.from(groups.entries()).map(([groupName, items]) => {
190
+ return (_jsxs(Fragment, { children: [groupName != null ? (_jsx(View, { style: [
191
+ styles.stickyHeader,
192
+ large && styles.stickyHeaderLarge,
193
+ { height: groupHeaderHeight },
194
+ ], children: _jsx(LakeHeading, { level: 3, variant: "h3", children: groupName }) })) : null, items.map((item, index) => {
195
+ const key = keyExtractor(item, index);
196
+ const isActive = activeRowId === key;
197
+ const isHovered = hoveredRow === key;
198
+ const wrapper = createRowWrapper({ item, absoluteIndex: index, extraInfo });
199
+ return cloneElement(wrapper, {
200
+ style: { ...styles.rowLink, ...wrapper.props.style },
201
+ key: index,
202
+ ref: isActive ? activeItemRef : null,
203
+ children: (_jsx(Row, { id: key, rowHeight: rowHeight, columns: displayColumns, item: item, index: index, extraInfo: extraInfo, isActive: isActive, isHovered: isHovered, large: large, onMouseEnter: setHoveredRow, onMouseLeave: removeHoveredRow })),
204
+ });
205
+ })] }, groupName));
206
+ }), _jsx(View, { children: _jsx(View, { accessibilityBusy: isLoading, style: styles.loadingPlaceholder, children: isLoading ? (_jsx(PlainListViewPlaceholder, { count: loading.count, rowHeight: rowHeight, rowVerticalSpacing: 0, paddingHorizontal: 0 })) : null }) })] }), originalData.length === 0 && isNotNullish(renderEmptyList) && !isLoading ? (_jsx(View, { style: styles.emptyListContainer, children: renderEmptyList() })) : null] }));
207
+ } }));
208
+ };
@@ -0,0 +1,23 @@
1
+ import { ReactNode, RefObject } from "react";
2
+ type Props = {
3
+ children: ReactNode | ((state: {
4
+ mode: "dropdown" | "panel";
5
+ }) => ReactNode);
6
+ id?: string;
7
+ label?: string;
8
+ role?: "listbox" | "combobox" | "dialog";
9
+ describedBy?: string;
10
+ matchReferenceWidth?: boolean;
11
+ matchReferenceMinWidth?: boolean;
12
+ onDismiss: () => void;
13
+ referenceRef: RefObject<unknown>;
14
+ returnFocus?: boolean;
15
+ autoFocus?: boolean;
16
+ visible: boolean;
17
+ underlay?: boolean;
18
+ safetyMargin?: number;
19
+ forcedMode?: "Dropdown" | "BottomPanel";
20
+ };
21
+ export declare const VIEWPORT_WIDTH_THRESHOLD = 600;
22
+ export declare const Popover: import("react").NamedExoticComponent<Props>;
23
+ export {};
@@ -0,0 +1,147 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo, useCallback, useEffect, useRef, useState } from "react";
3
+ import { Pressable, ScrollView, StyleSheet, View, } from "react-native";
4
+ import { match, P } from "ts-pattern";
5
+ import { animations, backgroundColor, radii, shadows } from "../constants/design";
6
+ import { useResponsive } from "../hooks/useResponsive";
7
+ import { BottomPanel } from "./BottomPanel";
8
+ import { FocusTrap } from "./FocusTrap";
9
+ import { Portal } from "./Portal";
10
+ import { TransitionView } from "./TransitionView";
11
+ const styles = StyleSheet.create({
12
+ container: {
13
+ ...StyleSheet.absoluteFillObject,
14
+ },
15
+ contents: {
16
+ ...StyleSheet.absoluteFillObject,
17
+ },
18
+ defaultCursor: {
19
+ cursor: "default",
20
+ },
21
+ underlay: {
22
+ cursor: "default",
23
+ position: "fixed",
24
+ left: 0,
25
+ top: 0,
26
+ bottom: 0,
27
+ right: 0,
28
+ },
29
+ popover: {
30
+ position: "absolute",
31
+ display: "flex",
32
+ flexDirection: "column",
33
+ backgroundColor: backgroundColor.accented,
34
+ borderRadius: radii[8],
35
+ marginVertical: 4,
36
+ overflow: "hidden",
37
+ boxShadow: shadows.modal,
38
+ },
39
+ popoverContents: {
40
+ alignItems: "stretch",
41
+ },
42
+ });
43
+ const DEFAULT_VIEWPORT_INFORMATION = {
44
+ availableSpaceAbove: 0,
45
+ availableSpaceBelow: 0,
46
+ availableSpaceBefore: 0,
47
+ availableSpaceAfter: 0,
48
+ top: 0,
49
+ bottom: 0,
50
+ left: 0,
51
+ right: 0,
52
+ availableHeight: 0,
53
+ width: 0,
54
+ };
55
+ const FLEX_END = "flex-end";
56
+ const FLEX_START = "flex-start";
57
+ const animation = {
58
+ ...animations.fadeAndSlideInFromBottom,
59
+ leave: StyleSheet.compose([animations.fadeAndSlideInFromBottom.leave], {
60
+ animationDuration: "100ms",
61
+ }),
62
+ };
63
+ export const VIEWPORT_WIDTH_THRESHOLD = 600;
64
+ export const Popover = memo(({ children, id, label, role = "dialog", describedBy, matchReferenceWidth = false, matchReferenceMinWidth = false, onDismiss, referenceRef, returnFocus = true, autoFocus = true, visible, underlay = true, safetyMargin = 8, forcedMode, }) => {
65
+ const [rootElement, setRootElement] = useState(null);
66
+ const underlayRef = useRef(null);
67
+ const { desktop } = useResponsive(VIEWPORT_WIDTH_THRESHOLD);
68
+ const [{ availableSpaceAbove, availableSpaceBelow, availableSpaceBefore, availableSpaceAfter, top, bottom, left, right, availableHeight, width, }, setViewportInformation,] = useState(DEFAULT_VIEWPORT_INFORMATION);
69
+ useEffect(() => {
70
+ const element = referenceRef.current;
71
+ if (element != null && visible) {
72
+ const rect = element.getBoundingClientRect();
73
+ const availableSpaceAbove = rect.top;
74
+ const availableSpaceBelow = window.innerHeight - rect.bottom;
75
+ setViewportInformation({
76
+ availableSpaceAbove,
77
+ availableSpaceBelow,
78
+ availableSpaceBefore: rect.left,
79
+ availableSpaceAfter: window.innerWidth - rect.right,
80
+ top: Math.max(rect.bottom, safetyMargin),
81
+ bottom: Math.max(window.innerHeight - rect.top, safetyMargin),
82
+ left: Math.max(rect.left, safetyMargin),
83
+ right: Math.max(window.innerWidth - rect.right, safetyMargin),
84
+ availableHeight: availableSpaceAbove <= availableSpaceBelow
85
+ ? window.innerHeight - rect.top - (rect.bottom - rect.top) - 20
86
+ : availableSpaceAbove - 20,
87
+ width: rect.right - rect.left,
88
+ });
89
+ }
90
+ }, [safetyMargin, referenceRef, visible]);
91
+ useEffect(() => {
92
+ const element = underlayRef.current;
93
+ if (!visible && element != null) {
94
+ element.style.pointerEvents = "none";
95
+ }
96
+ }, [visible]);
97
+ useEffect(() => {
98
+ const element = document.createElement("div");
99
+ document.body.append(element);
100
+ setRootElement(element);
101
+ return () => {
102
+ setRootElement(null);
103
+ element.remove();
104
+ };
105
+ }, []);
106
+ const onPressUnderlay = useCallback((event) => {
107
+ event.preventDefault();
108
+ onDismiss();
109
+ }, [onDismiss]);
110
+ const onClickOutside = useCallback(({ target }) => {
111
+ const ref = referenceRef.current;
112
+ if (!(ref instanceof Element) ||
113
+ !(target instanceof Element) ||
114
+ (ref !== target && !ref.contains(target))) {
115
+ onDismiss();
116
+ }
117
+ }, [referenceRef, onDismiss]);
118
+ const onPress = useCallback((event) => {
119
+ event.preventDefault();
120
+ }, []);
121
+ if (rootElement == null) {
122
+ return null;
123
+ }
124
+ const mode = match(forcedMode)
125
+ .with(P.nullish, () => (desktop ? "Dropdown" : "BottomPanel"))
126
+ .with("BottomPanel", () => "BottomPanel")
127
+ .with("Dropdown", () => "Dropdown")
128
+ .exhaustive();
129
+ if (mode === "BottomPanel") {
130
+ return (_jsx(BottomPanel, { visible: visible, onPressClose: onDismiss, returnFocus: false, children: typeof children == "function" ? children({ mode: "panel" }) : children }));
131
+ }
132
+ return (_jsx(Portal, { container: rootElement, children: _jsx(TransitionView, { pointerEvents: "none", style: styles.container, ...animation, children: visible ? (_jsxs(View, { style: styles.contents, children: [underlay ? (_jsx(Pressable, { ref: underlayRef, style: styles.underlay, onPress: onPressUnderlay, accessibilityRole: "button", accessibilityLabel: "Close", pointerEvents: "auto" })) : null, availableHeight > 0 ? (_jsx(ScrollView, { pointerEvents: "auto", style: [
133
+ styles.popover,
134
+ availableSpaceAbove <= availableSpaceBelow && { top },
135
+ availableSpaceAbove > availableSpaceBelow && { bottom },
136
+ availableSpaceBefore <= availableSpaceAfter && { left },
137
+ availableSpaceBefore > availableSpaceAfter && { right },
138
+ matchReferenceMinWidth && { minWidth: width },
139
+ matchReferenceWidth && { width },
140
+ { maxHeight: availableHeight },
141
+ ], contentContainerStyle: [
142
+ styles.popoverContents,
143
+ {
144
+ justifyContent: availableSpaceAbove > availableSpaceBelow ? FLEX_END : FLEX_START,
145
+ },
146
+ ], nativeID: id, accessibilityRole: role, accessibilityDescribedBy: describedBy, accessibilityLabel: label, children: _jsx(FocusTrap, { focusLock: true, returnFocus: returnFocus, autoFocus: autoFocus, onEscapeKey: onDismiss, onClickOutside: underlay ? undefined : onClickOutside, children: _jsx(Pressable, { focusable: false, onPress: onPress, style: styles.defaultCursor, children: typeof children == "function" ? children({ mode: "dropdown" }) : children }) }) })) : null] })) : null }) }));
147
+ });
@@ -0,0 +1,8 @@
1
+ import { ReactNode } from "react";
2
+ import { StyleProp, ViewStyle } from "react-native";
3
+ type Props = {
4
+ children: ReactNode;
5
+ style?: StyleProp<ViewStyle>;
6
+ };
7
+ export declare const PopoverContent: ({ style, children }: Props) => JSX.Element;
8
+ export {};
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { StyleSheet, View } from "react-native";
3
+ const styles = StyleSheet.create({
4
+ container: {
5
+ overflow: "hidden",
6
+ padding: 20,
7
+ },
8
+ });
9
+ export const PopoverContent = ({ style, children }) => (_jsx(View, { style: [styles.container, style], children: children }));
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from "react";
2
+ type Props = {
3
+ children: ReactNode;
4
+ container: Element;
5
+ };
6
+ export declare const Portal: ({ children, container }: Props) => import("react").ReactPortal;
7
+ export {};
@@ -0,0 +1,9 @@
1
+ import { useContext, useRef } from "react";
2
+ import * as ReactDOM from "react-dom";
3
+ import { CurrentColorContext, useCurrentColor } from "./WithCurrentColor";
4
+ export const Portal = ({ children, container }) => {
5
+ const currentColor = useContext(CurrentColorContext);
6
+ const containerRef = useRef(container);
7
+ useCurrentColor(containerRef, currentColor);
8
+ return ReactDOM.createPortal(children, container);
9
+ };