@brand-map/primitives 0.0.0-broken.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 (121) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.oxfmtrc.json +35 -0
  4. package/.oxlintrc.json +166 -0
  5. package/README.md +78 -0
  6. package/bun.lock +904 -0
  7. package/mise.toml +3 -0
  8. package/package.json +61 -0
  9. package/src/accordion/accordion.tsx +189 -0
  10. package/src/accordion/accordion.web.tsx +282 -0
  11. package/src/accordion/index.ts +2 -0
  12. package/src/accordion/types.ts +44 -0
  13. package/src/alert-dialog/alert-dialog.tsx +238 -0
  14. package/src/alert-dialog/alert-dialog.web.tsx +260 -0
  15. package/src/alert-dialog/index.ts +2 -0
  16. package/src/alert-dialog/types.ts +81 -0
  17. package/src/aspect-ratio/aspect-ratio.tsx +27 -0
  18. package/src/aspect-ratio/index.ts +1 -0
  19. package/src/avatar/avatar.tsx +122 -0
  20. package/src/avatar/index.ts +2 -0
  21. package/src/avatar/types.ts +20 -0
  22. package/src/checkbox/checkbox.tsx +95 -0
  23. package/src/checkbox/checkbox.web.tsx +111 -0
  24. package/src/checkbox/index.ts +2 -0
  25. package/src/checkbox/types.ts +14 -0
  26. package/src/collapsible/collapsible.tsx +98 -0
  27. package/src/collapsible/collapsible.web.tsx +149 -0
  28. package/src/collapsible/index.ts +2 -0
  29. package/src/collapsible/types.ts +23 -0
  30. package/src/context-menu/context-menu.tsx +616 -0
  31. package/src/context-menu/context-menu.web.tsx +560 -0
  32. package/src/context-menu/index.ts +2 -0
  33. package/src/context-menu/types.ts +136 -0
  34. package/src/dialog/dialog.tsx +286 -0
  35. package/src/dialog/dialog.web.tsx +215 -0
  36. package/src/dialog/index.ts +2 -0
  37. package/src/dialog/types.ts +92 -0
  38. package/src/dropdown-menu/dropdown-menu.tsx +575 -0
  39. package/src/dropdown-menu/dropdown-menu.web.tsx +565 -0
  40. package/src/dropdown-menu/index.ts +2 -0
  41. package/src/dropdown-menu/types.ts +121 -0
  42. package/src/hooks/index.ts +4 -0
  43. package/src/hooks/use-Isomorphic-layout-effect.tsx +12 -0
  44. package/src/hooks/use-augmented-ref.tsx +25 -0
  45. package/src/hooks/use-controllable-state.tsx +70 -0
  46. package/src/hooks/use-relative-position.tsx +175 -0
  47. package/src/hover-card/hover-card.tsx +255 -0
  48. package/src/hover-card/hover-card.web.tsx +161 -0
  49. package/src/hover-card/index.ts +2 -0
  50. package/src/hover-card/types.ts +56 -0
  51. package/src/label/index.ts +2 -0
  52. package/src/label/label.tsx +36 -0
  53. package/src/label/label.web.tsx +38 -0
  54. package/src/label/types.ts +24 -0
  55. package/src/menubar/index.ts +2 -0
  56. package/src/menubar/menubar.tsx +602 -0
  57. package/src/menubar/menubar.web.tsx +575 -0
  58. package/src/menubar/types.ts +126 -0
  59. package/src/navigation-menu/index.ts +2 -0
  60. package/src/navigation-menu/navigation-menu.tsx +302 -0
  61. package/src/navigation-menu/navigation-menu.web.tsx +259 -0
  62. package/src/navigation-menu/types.ts +85 -0
  63. package/src/popover/index.ts +2 -0
  64. package/src/popover/popover.tsx +279 -0
  65. package/src/popover/popover.web.tsx +217 -0
  66. package/src/popover/types.ts +44 -0
  67. package/src/portal/index.ts +1 -0
  68. package/src/portal/portal.tsx +56 -0
  69. package/src/progress/index.ts +2 -0
  70. package/src/progress/progress.tsx +59 -0
  71. package/src/progress/progress.web.tsx +46 -0
  72. package/src/progress/types.ts +14 -0
  73. package/src/radio-group/index.ts +2 -0
  74. package/src/radio-group/radio-group.tsx +106 -0
  75. package/src/radio-group/radio-group.web.tsx +85 -0
  76. package/src/radio-group/types.ts +24 -0
  77. package/src/select/index.ts +2 -0
  78. package/src/select/select.tsx +447 -0
  79. package/src/select/select.web.tsx +368 -0
  80. package/src/select/types.ts +145 -0
  81. package/src/separator/index.ts +2 -0
  82. package/src/separator/separator.tsx +21 -0
  83. package/src/separator/types.ts +10 -0
  84. package/src/slider/index.ts +2 -0
  85. package/src/slider/slider.tsx +77 -0
  86. package/src/slider/slider.web.tsx +75 -0
  87. package/src/slider/types.ts +39 -0
  88. package/src/slot/index.ts +1 -0
  89. package/src/slot/slot.tsx +224 -0
  90. package/src/switch/index.ts +2 -0
  91. package/src/switch/switch.tsx +49 -0
  92. package/src/switch/switch.web.tsx +60 -0
  93. package/src/switch/types.ts +19 -0
  94. package/src/table/index.ts +1 -0
  95. package/src/table/table.tsx +121 -0
  96. package/src/tabs/index.ts +2 -0
  97. package/src/tabs/tabs.tsx +120 -0
  98. package/src/tabs/tabs.web.tsx +106 -0
  99. package/src/tabs/types.ts +37 -0
  100. package/src/toast/index.ts +2 -0
  101. package/src/toast/toast.tsx +124 -0
  102. package/src/toast/types.ts +20 -0
  103. package/src/toggle/index.ts +2 -0
  104. package/src/toggle/toggle.tsx +35 -0
  105. package/src/toggle/toggle.web.tsx +36 -0
  106. package/src/toggle/types.ts +11 -0
  107. package/src/toggle-group/index.ts +2 -0
  108. package/src/toggle-group/toggle-group.tsx +100 -0
  109. package/src/toggle-group/toggle-group.web.tsx +103 -0
  110. package/src/toggle-group/types.ts +46 -0
  111. package/src/toolbar/index.ts +2 -0
  112. package/src/toolbar/toolbar.tsx +141 -0
  113. package/src/toolbar/toolbar.web.tsx +158 -0
  114. package/src/toolbar/types.ts +64 -0
  115. package/src/tooltip/index.ts +2 -0
  116. package/src/tooltip/tooltip.tsx +261 -0
  117. package/src/tooltip/tooltip.web.tsx +175 -0
  118. package/src/tooltip/types.ts +61 -0
  119. package/src/types/index.ts +141 -0
  120. package/src/utils/index.ts +69 -0
  121. package/tsconfig.json +23 -0
@@ -0,0 +1,141 @@
1
+ import * as React from "react";
2
+ import { Pressable, View, type GestureResponderEvent } from "react-native";
3
+
4
+ import * as Slot from "../slot";
5
+ import { ToggleGroupUtils } from "../utils";
6
+
7
+ import type {
8
+ ButtonProps,
9
+ ButtonRef,
10
+ LinkProps,
11
+ LinkRef,
12
+ RootProps,
13
+ RootRef,
14
+ SeparatorProps,
15
+ SeparatorRef,
16
+ ToggleGroupProps,
17
+ ToggleGroupRef,
18
+ ToggleItemProps,
19
+ ToggleItemRef,
20
+ } from "./types";
21
+
22
+ const Root = React.forwardRef<RootRef, RootProps>(({ orientation: _orientation, dir: _dir, loop: _loop, ...props }, ref) => {
23
+ return (
24
+ <Component
25
+ ref={ref}
26
+ role="toolbar"
27
+ {...props}
28
+ />
29
+ );
30
+ });
31
+
32
+ Root.displayName = "RootNativeToolbar";
33
+
34
+ const ToggleGroupContext = React.createContext<ToggleGroupProps | null>(null);
35
+
36
+ const ToggleGroup = React.forwardRef<ToggleGroupRef, ToggleGroupProps>(({ type, value, onValueChange, disabled = false, ...viewProps }, ref) => {
37
+ return (
38
+ <ToggleGroupContext.Provider
39
+ value={
40
+ {
41
+ type,
42
+ value,
43
+ disabled,
44
+ onValueChange,
45
+ } as ToggleGroupProps
46
+ }
47
+ >
48
+ <Component
49
+ ref={ref}
50
+ role="group"
51
+ {...viewProps}
52
+ />
53
+ </ToggleGroupContext.Provider>
54
+ );
55
+ });
56
+
57
+ ToggleGroup.displayName = "ToggleGroupNativeToolbar";
58
+
59
+ function useToggleGroupContext() {
60
+ const context = React.useContext(ToggleGroupContext);
61
+ if (!context) {
62
+ throw new Error("ToggleGroup compound components cannot be rendered outside the ToggleGroup component");
63
+ }
64
+ return context;
65
+ }
66
+
67
+ const ToggleItem = React.forwardRef<ToggleItemRef, ToggleItemProps>(
68
+ ({ render, value: itemValue, disabled: disabledProp = false, onPress: onPressProp, ...props }, ref) => {
69
+ const { type, disabled, value, onValueChange } = useToggleGroupContext();
70
+
71
+ function onPress(ev: GestureResponderEvent) {
72
+ if (disabled || disabledProp) return;
73
+ if (type === "single") {
74
+ onValueChange(ToggleGroupUtils.getNewSingleValue(value, itemValue));
75
+ }
76
+ if (type === "multiple") {
77
+ onValueChange(ToggleGroupUtils.getNewMultipleValue(value, itemValue));
78
+ }
79
+ onPressProp?.(ev);
80
+ }
81
+
82
+ const isChecked = type === "single" ? ToggleGroupUtils.getIsSelected(value, itemValue) : undefined;
83
+ const isSelected = type === "multiple" ? ToggleGroupUtils.getIsSelected(value, itemValue) : undefined;
84
+
85
+ return (
86
+ <Component
87
+ ref={ref}
88
+ aria-disabled={disabled}
89
+ role={type === "single" ? "radio" : "checkbox"}
90
+ onPress={onPress}
91
+ aria-checked={isChecked}
92
+ aria-selected={isSelected}
93
+ disabled={(disabled || disabledProp) ?? false}
94
+ accessibilityState={{
95
+ disabled: (disabled || disabledProp) ?? false,
96
+ checked: isChecked,
97
+ selected: isSelected,
98
+ }}
99
+ {...props}
100
+ />
101
+ );
102
+ },
103
+ );
104
+
105
+ ToggleItem.displayName = "ToggleItemNativeToolbar";
106
+
107
+ const Separator = React.forwardRef<SeparatorRef, SeparatorProps>(({ ...props }, ref) => {
108
+ return (
109
+ <Component
110
+ role={"separator"}
111
+ ref={ref}
112
+ {...props}
113
+ />
114
+ );
115
+ });
116
+
117
+ Separator.displayName = "SeparatorNativeToolbar";
118
+
119
+ const Link = React.forwardRef<LinkRef, LinkProps>(({ ...props }, ref) => {
120
+ return (
121
+ <Component
122
+ ref={ref}
123
+ role="link"
124
+ {...props}
125
+ />
126
+ );
127
+ });
128
+
129
+ Link.displayName = "LinkNativeToolbar";
130
+
131
+ const Button = React.forwardRef<ButtonRef, ButtonProps>(({ ...props }, ref) => {
132
+ return (
133
+ <Component
134
+ ref={ref}
135
+ role="button"
136
+ {...props}
137
+ />
138
+ );
139
+ });
140
+
141
+ export { Button, Link, Root, Separator, ToggleGroup, ToggleItem };
@@ -0,0 +1,158 @@
1
+ // import * as Toolbar from "@radix-ui/react-toolbar";
2
+ // import * as React from "react";
3
+ // import { Pressable, View, type GestureResponderEvent } from "react-native";
4
+
5
+ // import * as Slot from "../slot";
6
+ // import { ToggleGroupUtils } from "../utils";
7
+
8
+ // import type {
9
+ // ButtonProps,
10
+ // ButtonRef,
11
+ // LinkProps,
12
+ // LinkRef,
13
+ // RootProps,
14
+ // RootRef,
15
+ // SeparatorProps,
16
+ // SeparatorRef,
17
+ // ToggleGroupProps,
18
+ // ToggleGroupRef,
19
+ // ToggleItemProps,
20
+ // ToggleItemRef,
21
+ // } from "./types";
22
+
23
+ // const Root = React.forwardRef<RootRef, RootProps>(({ orientation, dir, loop, style, ...props }, ref) => {
24
+ //
25
+ // return (
26
+ // <Toolbar.Root
27
+ // orientation={orientation}
28
+ // dir={dir}
29
+ // loop={loop}
30
+ // render
31
+ // >
32
+ // <Component
33
+ // ref={ref}
34
+ // {...props}
35
+ // />
36
+ // </Toolbar.Root>
37
+ // );
38
+ // });
39
+
40
+ // Root.displayName = "RootWebToolbar";
41
+
42
+ // const ToggleGroupContext = React.createContext<ToggleGroupProps | null>(null);
43
+
44
+ // const ToggleGroup = React.forwardRef<ToggleGroupRef, ToggleGroupProps>(
45
+ // ({ render, type, value, onValueChange, disabled = false, style, ...viewProps }, ref) => {
46
+ //
47
+ // return (
48
+ // <ToggleGroupContext.Provider
49
+ // value={
50
+ // {
51
+ // type,
52
+ // value,
53
+ // disabled,
54
+ // onValueChange,
55
+ // } as ToggleGroupProps
56
+ // }
57
+ // >
58
+ // <Toolbar.ToggleGroup
59
+ // type={type as any}
60
+ // value={value as any}
61
+ // onValueChange={onValueChange as any}
62
+ // disabled={disabled}
63
+ // render
64
+ // >
65
+ // <Component
66
+ // ref={ref}
67
+ // {...viewProps}
68
+ // />
69
+ // </Toolbar.ToggleGroup>
70
+ // </ToggleGroupContext.Provider>
71
+ // );
72
+ // },
73
+ // );
74
+
75
+ // ToggleGroup.displayName = "ToggleGroupWebToolbar";
76
+
77
+ // function useToggleGroupContext() {
78
+ // const context = React.useContext(ToggleGroupContext);
79
+ // if (!context) {
80
+ // throw new Error("ToggleGroup compound components cannot be rendered outside the ToggleGroup component");
81
+ // }
82
+ // return context;
83
+ // }
84
+
85
+ // const ToggleItem = React.forwardRef<ToggleItemRef, ToggleItemProps>(
86
+ // ({ render, value: itemValue, disabled: disabledProp = false, onPress: onPressProp, style, ...props }, ref) => {
87
+ // const { type, disabled, value, onValueChange } = useToggleGroupContext();
88
+
89
+ // function onPress(ev: GestureResponderEvent) {
90
+ // if (disabled || disabledProp) return;
91
+ // if (type === "single") {
92
+ // onValueChange(ToggleGroupUtils.getNewSingleValue(value, itemValue));
93
+ // }
94
+ // if (type === "multiple") {
95
+ // onValueChange(ToggleGroupUtils.getNewMultipleValue(value, itemValue));
96
+ // }
97
+ // onPressProp?.(ev);
98
+ // }
99
+
100
+ //
101
+ // return (
102
+ // <Toolbar.ToggleItem
103
+ // value={itemValue}
104
+ // render
105
+ // >
106
+ // <Component
107
+ // ref={ref}
108
+ // onPress={onPress}
109
+ // role="button"
110
+ // {...props}
111
+ // />
112
+ // </Toolbar.ToggleItem>
113
+ // );
114
+ // },
115
+ // );
116
+
117
+ // ToggleItem.displayName = "ToggleItemWebToolbar";
118
+
119
+ // const Separator = React.forwardRef<SeparatorRef, SeparatorProps>(({ style, ...props }, ref) => {
120
+ //
121
+ // return (
122
+ // <Component
123
+ // ref={ref}
124
+ // {...props}
125
+ // />
126
+ // );
127
+ // });
128
+
129
+ // Separator.displayName = "SeparatorWebToolbar";
130
+
131
+ // const Link = React.forwardRef<LinkRef, LinkProps>(({ style, ...props }, ref) => {
132
+ //
133
+ // return (
134
+ // <Toolbar.Link render>
135
+ // <Component
136
+ // ref={ref}
137
+ // {...props}
138
+ // />
139
+ // </Toolbar.Link>
140
+ // );
141
+ // });
142
+
143
+ // Link.displayName = "LinkWebToolbar";
144
+
145
+ // const Button = React.forwardRef<ButtonRef, ButtonProps>(({ style, ...props }, ref) => {
146
+ //
147
+ // return (
148
+ // <Toolbar.Button render>
149
+ // <Component
150
+ // ref={ref}
151
+ // role="button"
152
+ // {...props}
153
+ // />
154
+ // </Toolbar.Button>
155
+ // );
156
+ // });
157
+
158
+ // export { Button, Link, Root, Separator, ToggleGroup, ToggleItem };
@@ -0,0 +1,64 @@
1
+ import type { PressableRef, RenderPressableProps, RenderViewProps, ViewRef } from "../types";
2
+
3
+ type RootProps = RenderViewProps & {
4
+ /**
5
+ * @platform: WEB ONLY
6
+ */
7
+ orientation?: "horizontal" | "vertical";
8
+
9
+ /**
10
+ * @platform: WEB ONLY
11
+ */
12
+ dir?: "ltr" | "rtl";
13
+
14
+ /**
15
+ * @platform: WEB ONLY
16
+ */
17
+ loop?: boolean;
18
+ };
19
+
20
+ type SingleToggleGroupProps = {
21
+ type: "single";
22
+ value: string | undefined;
23
+ onValueChange: (val: string | undefined) => void;
24
+ };
25
+
26
+ type MultipleToggleGroupProps = {
27
+ type: "multiple";
28
+ value: string[];
29
+ onValueChange: (val: string[]) => void;
30
+ };
31
+
32
+ type ToggleGroupProps = (SingleToggleGroupProps | MultipleToggleGroupProps) & {
33
+ disabled?: boolean;
34
+ } & RenderViewProps;
35
+
36
+ type ToggleItemProps = RenderPressableProps & {
37
+ value: string;
38
+ };
39
+
40
+ type SeparatorProps = RenderViewProps;
41
+ type LinkProps = RenderPressableProps;
42
+ type ButtonProps = RenderPressableProps;
43
+
44
+ type RootRef = ViewRef;
45
+ type LinkRef = PressableRef;
46
+ type ButtonRef = PressableRef;
47
+ type SeparatorRef = ViewRef;
48
+ type ToggleGroupRef = ViewRef;
49
+ type ToggleItemRef = PressableRef;
50
+
51
+ export type {
52
+ ButtonProps,
53
+ ButtonRef,
54
+ LinkProps,
55
+ LinkRef,
56
+ RootProps,
57
+ RootRef,
58
+ SeparatorProps,
59
+ SeparatorRef,
60
+ ToggleGroupProps,
61
+ ToggleGroupRef,
62
+ ToggleItemProps,
63
+ ToggleItemRef,
64
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./tooltip";
2
+ export * from "./types";
@@ -0,0 +1,261 @@
1
+ import * as React from "react";
2
+ import { BackHandler, Pressable, View, type GestureResponderEvent, type LayoutChangeEvent, type LayoutRectangle } from "react-native";
3
+
4
+ import { useAugmentedRef, useRelativePosition, type LayoutPosition } from "../hooks";
5
+ import { Portal as RNPPortal } from "../portal";
6
+ import * as Slot from "../slot";
7
+
8
+ import type { ContentProps, ContentRef, BackdropProps, BackdropRef, PortalProps, RootProps, RootRef, TriggerProps, TriggerRef } from "./types";
9
+
10
+ interface RootContextInterface {
11
+ open: boolean;
12
+ onOpenChange: (open: boolean) => void;
13
+ triggerPosition: LayoutPosition | null;
14
+ setTriggerPosition: (triggerPosition: LayoutPosition | null) => void;
15
+ contentLayout: LayoutRectangle | null;
16
+ setContentLayout: (contentLayout: LayoutRectangle | null) => void;
17
+ nativeID: string;
18
+ }
19
+
20
+ const RootContext = React.createContext<RootContextInterface | null>(null);
21
+
22
+ const Root = React.forwardRef<RootRef, RootProps>(
23
+ (
24
+ {
25
+ render,
26
+ delayDuration: _delayDuration,
27
+ skipDelayDuration: _skipDelayDuration,
28
+ disableHoverableContent: _disableHoverableContent,
29
+ onOpenChange: onOpenChangeProp,
30
+ ...viewProps
31
+ },
32
+ ref,
33
+ ) => {
34
+ const nativeID = React.useId();
35
+ const [triggerPosition, setTriggerPosition] = React.useState<LayoutPosition | null>(null);
36
+ const [contentLayout, setContentLayout] = React.useState<LayoutRectangle | null>(null);
37
+ const [open, setOpen] = React.useState(false);
38
+
39
+ function onOpenChange(value: boolean) {
40
+ setOpen(value);
41
+ onOpenChangeProp?.(value);
42
+ }
43
+
44
+ return (
45
+ <RootContext.Provider
46
+ value={{
47
+ open,
48
+ onOpenChange,
49
+ contentLayout,
50
+ nativeID,
51
+ setContentLayout,
52
+ setTriggerPosition,
53
+ triggerPosition,
54
+ }}
55
+ >
56
+ <Component
57
+ ref={ref}
58
+ {...viewProps}
59
+ />
60
+ </RootContext.Provider>
61
+ );
62
+ },
63
+ );
64
+
65
+ Root.displayName = "RootNativeTooltip";
66
+
67
+ function useTooltipContext() {
68
+ const context = React.useContext(RootContext);
69
+ if (!context) {
70
+ throw new Error("Tooltip compound components cannot be rendered outside the Tooltip component");
71
+ }
72
+ return context;
73
+ }
74
+
75
+ const Trigger = React.forwardRef<TriggerRef, TriggerProps>(({ onPress: onPressProp, disabled = false, ...props }, ref) => {
76
+ const { open, onOpenChange, setTriggerPosition } = useTooltipContext();
77
+
78
+ const augmentedRef = useAugmentedRef({
79
+ ref,
80
+ methods: {
81
+ open: () => {
82
+ onOpenChange(true);
83
+ augmentedRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
84
+ setTriggerPosition({ width, pageX, pageY: pageY, height });
85
+ });
86
+ },
87
+ close: () => {
88
+ setTriggerPosition(null);
89
+ onOpenChange(false);
90
+ },
91
+ },
92
+ });
93
+
94
+ function onPress(ev: GestureResponderEvent) {
95
+ if (disabled) return;
96
+ augmentedRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
97
+ setTriggerPosition({ width, pageX, pageY: pageY, height });
98
+ });
99
+ const newValue = !open;
100
+ onOpenChange(newValue);
101
+ onPressProp?.(ev);
102
+ }
103
+
104
+ return (
105
+ <Component
106
+ ref={augmentedRef}
107
+ aria-disabled={disabled ?? undefined}
108
+ role="button"
109
+ onPress={onPress}
110
+ disabled={disabled ?? undefined}
111
+ {...props}
112
+ />
113
+ );
114
+ });
115
+
116
+ Trigger.displayName = "TriggerNativeTooltip";
117
+
118
+ /**
119
+ * @warning when using a custom `<PortalHost />`, you might have to adjust the Content's sideOffset to account for nav elements like headers.
120
+ */
121
+ function Portal({ keepMounted, hostName, children }: PortalProps) {
122
+ const value = useTooltipContext();
123
+
124
+ if (!value.triggerPosition) {
125
+ return null;
126
+ }
127
+
128
+ if (!keepMounted) {
129
+ if (!value.open) {
130
+ return null;
131
+ }
132
+ }
133
+
134
+ return (
135
+ <RNPPortal
136
+ hostName={hostName}
137
+ name={`${value.nativeID}_portal`}
138
+ >
139
+ <RootContext.Provider value={value}>{children}</RootContext.Provider>
140
+ </RNPPortal>
141
+ );
142
+ }
143
+
144
+ const Backdrop = React.forwardRef<BackdropRef, BackdropProps>(({ keepMounted, onPress: OnPressProp, closeOnPress = true, ...props }, ref) => {
145
+ const { open, onOpenChange, setContentLayout, setTriggerPosition } = useTooltipContext();
146
+
147
+ function onPress(ev: GestureResponderEvent) {
148
+ if (closeOnPress) {
149
+ setTriggerPosition(null);
150
+ setContentLayout(null);
151
+ onOpenChange(false);
152
+ }
153
+ OnPressProp?.(ev);
154
+ }
155
+
156
+ if (!keepMounted) {
157
+ if (!open) {
158
+ return null;
159
+ }
160
+ }
161
+
162
+ return (
163
+ <Component
164
+ ref={ref}
165
+ onPress={onPress}
166
+ {...props}
167
+ />
168
+ );
169
+ });
170
+
171
+ Backdrop.displayName = "BackdropNativeTooltip";
172
+
173
+ /**
174
+ * @info `position`, `top`, `left`, and `maxWidth` style properties are controlled internally. Opt out of this behavior on native by setting `disablePositioningStyle` to `true`.
175
+ */
176
+ const Content = React.forwardRef<ContentRef, ContentProps>(
177
+ (
178
+ {
179
+ render = false,
180
+ keepMounted,
181
+ align = "center",
182
+ side = "top",
183
+ sideOffset = 0,
184
+ alignOffset = 0,
185
+ avoidCollisions = true,
186
+ onLayout: onLayoutProp,
187
+ insets,
188
+ style,
189
+ disablePositioningStyle,
190
+ ...props
191
+ },
192
+ ref,
193
+ ) => {
194
+ const { open, onOpenChange, nativeID, contentLayout, setContentLayout, setTriggerPosition, triggerPosition } = useTooltipContext();
195
+
196
+ React.useEffect(() => {
197
+ const backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
198
+ setTriggerPosition(null);
199
+ setContentLayout(null);
200
+ onOpenChange(false);
201
+ return true;
202
+ });
203
+
204
+ return () => {
205
+ setContentLayout(null);
206
+ backHandler.remove();
207
+ };
208
+ }, []);
209
+
210
+ const positionStyle = useRelativePosition({
211
+ align,
212
+ avoidCollisions,
213
+ triggerPosition,
214
+ contentLayout,
215
+ alignOffset,
216
+ insets,
217
+ sideOffset,
218
+ side: getNativeSide(side),
219
+ disablePositioningStyle,
220
+ });
221
+
222
+ function onLayout(event: LayoutChangeEvent) {
223
+ setContentLayout(event.nativeEvent.layout);
224
+ onLayoutProp?.(event);
225
+ }
226
+
227
+ if (!keepMounted) {
228
+ if (!open) {
229
+ return null;
230
+ }
231
+ }
232
+
233
+ return (
234
+ <Component
235
+ ref={ref}
236
+ role="tooltip"
237
+ nativeID={nativeID}
238
+ aria-modal={true}
239
+ style={[positionStyle, style]}
240
+ onLayout={onLayout}
241
+ onStartShouldSetResponder={onStartShouldSetResponder}
242
+ {...props}
243
+ />
244
+ );
245
+ },
246
+ );
247
+
248
+ Content.displayName = "ContentNativeTooltip";
249
+
250
+ export { Content, Backdrop, Portal, Root, Trigger };
251
+
252
+ function onStartShouldSetResponder() {
253
+ return true;
254
+ }
255
+
256
+ function getNativeSide(side: "left" | "right" | "top" | "bottom") {
257
+ if (side === "left" || side === "right") {
258
+ return "top";
259
+ }
260
+ return side;
261
+ }