@korsolutions/ui 0.0.59 → 0.0.60
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.
- package/dist/module/components/menu/components/menu-checkbox-item.js +4 -4
- package/dist/module/components/menu/components/menu-checkbox-item.js.map +1 -1
- package/dist/module/components/menu/components/menu-content.js +1 -1
- package/dist/module/components/menu/components/menu-radio-item.js +4 -4
- package/dist/module/components/menu/components/menu-radio-item.js.map +1 -1
- package/dist/module/components/menu/components/menu-selection-indicator.js +29 -0
- package/dist/module/components/menu/components/menu-selection-indicator.js.map +1 -0
- package/dist/module/components/menu/variants/default.js +8 -17
- package/dist/module/components/menu/variants/default.js.map +1 -1
- package/dist/module/components/phone-input/components/country-picker.js +1 -1
- package/dist/module/components/popover/components/popover-content.js +2 -5
- package/dist/module/components/popover/components/popover-content.js.map +1 -1
- package/dist/module/components/portal/index.js +1 -0
- package/dist/module/components/portal/index.js.map +1 -1
- package/dist/module/components/portal/portal-offset.js +32 -0
- package/dist/module/components/portal/portal-offset.js.map +1 -0
- package/dist/module/components/portal/portal.js +39 -17
- package/dist/module/components/portal/portal.js.map +1 -1
- package/dist/module/components/select/components/select-content.js +3 -3
- package/dist/module/components/select/components/select-content.js.map +1 -1
- package/dist/module/components/textarea/variants/default.js +7 -0
- package/dist/module/components/textarea/variants/default.js.map +1 -1
- package/dist/module/hooks/use-relative-position.js +37 -28
- package/dist/module/hooks/use-relative-position.js.map +1 -1
- package/dist/module/themes/provider.js.map +1 -1
- package/dist/typescript/src/components/menu/components/menu-checkbox-item.d.ts.map +1 -1
- package/dist/typescript/src/components/menu/components/menu-radio-item.d.ts.map +1 -1
- package/dist/typescript/src/components/menu/components/menu-selection-indicator.d.ts +7 -0
- package/dist/typescript/src/components/menu/components/menu-selection-indicator.d.ts.map +1 -0
- package/dist/typescript/src/components/menu/types.d.ts +1 -3
- package/dist/typescript/src/components/menu/types.d.ts.map +1 -1
- package/dist/typescript/src/components/menu/variants/default.d.ts.map +1 -1
- package/dist/typescript/src/components/popover/components/popover-content.d.ts.map +1 -1
- package/dist/typescript/src/components/portal/index.d.ts +1 -0
- package/dist/typescript/src/components/portal/index.d.ts.map +1 -1
- package/dist/typescript/src/components/portal/portal-offset.d.ts +13 -0
- package/dist/typescript/src/components/portal/portal-offset.d.ts.map +1 -0
- package/dist/typescript/src/components/portal/portal.d.ts +3 -2
- package/dist/typescript/src/components/portal/portal.d.ts.map +1 -1
- package/dist/typescript/src/components/select/components/select-content.d.ts.map +1 -1
- package/dist/typescript/src/components/textarea/variants/default.d.ts.map +1 -1
- package/dist/typescript/src/hooks/use-relative-position.d.ts +4 -7
- package/dist/typescript/src/hooks/use-relative-position.d.ts.map +1 -1
- package/dist/typescript/src/themes/provider.d.ts +3 -0
- package/dist/typescript/src/themes/provider.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/menu/components/menu-checkbox-item.tsx +3 -4
- package/src/components/menu/components/menu-content.tsx +1 -1
- package/src/components/menu/components/menu-radio-item.tsx +3 -7
- package/src/components/menu/components/menu-selection-indicator.tsx +26 -0
- package/src/components/menu/types.ts +1 -6
- package/src/components/menu/variants/default.tsx +7 -16
- package/src/components/phone-input/components/country-picker.tsx +1 -1
- package/src/components/popover/components/popover-content.tsx +1 -4
- package/src/components/portal/index.ts +1 -0
- package/src/components/portal/portal-offset.ts +28 -0
- package/src/components/portal/portal.tsx +54 -22
- package/src/components/select/components/select-content.tsx +14 -5
- package/src/components/textarea/variants/default.tsx +7 -0
- package/src/hooks/use-relative-position.ts +53 -41
- package/src/themes/provider.tsx +3 -0
|
@@ -5,29 +5,35 @@ import {
|
|
|
5
5
|
type LayoutRectangle,
|
|
6
6
|
type ViewStyle,
|
|
7
7
|
} from "react-native";
|
|
8
|
-
import
|
|
8
|
+
import { usePortalOffset } from "../components/portal";
|
|
9
|
+
import { useSafeAreaInsets, type SafeAreaInsets } from "../safe-area";
|
|
9
10
|
|
|
10
11
|
type UseRelativePositionArgs = Omit<
|
|
11
12
|
GetContentStyleArgs,
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
triggerPosition: LayoutPosition | null;
|
|
15
|
-
contentLayout: LayoutRectangle | null;
|
|
16
|
-
};
|
|
13
|
+
"dimensions" | "insets"
|
|
14
|
+
>;
|
|
17
15
|
|
|
18
16
|
export function useRelativePosition({
|
|
19
17
|
align,
|
|
20
18
|
triggerPosition,
|
|
21
19
|
contentLayout,
|
|
22
20
|
alignOffset,
|
|
23
|
-
insets,
|
|
24
21
|
sideOffset,
|
|
25
22
|
preferredSide,
|
|
26
23
|
}: UseRelativePositionArgs): ViewStyle {
|
|
27
24
|
const dimensions = useWindowDimensions();
|
|
25
|
+
const insets = useSafeAreaInsets();
|
|
26
|
+
const portalOffset = usePortalOffset();
|
|
28
27
|
|
|
29
28
|
return useMemo(() => {
|
|
30
|
-
|
|
29
|
+
const hasLayout =
|
|
30
|
+
triggerPosition.width > 0 &&
|
|
31
|
+
triggerPosition.height > 0 &&
|
|
32
|
+
contentLayout.width > 0 &&
|
|
33
|
+
contentLayout.height > 0 &&
|
|
34
|
+
portalOffset.isLoaded;
|
|
35
|
+
|
|
36
|
+
if (!hasLayout) {
|
|
31
37
|
return {
|
|
32
38
|
position: "absolute",
|
|
33
39
|
opacity: 0,
|
|
@@ -36,11 +42,22 @@ export function useRelativePosition({
|
|
|
36
42
|
};
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
// Adjust trigger position to account for the portal container's
|
|
46
|
+
// offset from the window origin. measureInWindow returns window-relative
|
|
47
|
+
// coordinates, but the portal content is positioned relative to its
|
|
48
|
+
// container which may not be at the window origin (e.g. on Android
|
|
49
|
+
// where the status bar offsets the view hierarchy).
|
|
50
|
+
const adjustedTriggerPosition: LayoutPosition = {
|
|
51
|
+
...triggerPosition,
|
|
52
|
+
pageX: triggerPosition.pageX - portalOffset.value.x,
|
|
53
|
+
pageY: triggerPosition.pageY - portalOffset.value.y,
|
|
54
|
+
};
|
|
55
|
+
|
|
39
56
|
const style = getContentStyle({
|
|
40
57
|
align,
|
|
41
58
|
contentLayout,
|
|
42
59
|
preferredSide,
|
|
43
|
-
triggerPosition,
|
|
60
|
+
triggerPosition: adjustedTriggerPosition,
|
|
44
61
|
alignOffset,
|
|
45
62
|
insets,
|
|
46
63
|
sideOffset,
|
|
@@ -58,6 +75,7 @@ export function useRelativePosition({
|
|
|
58
75
|
dimensions.width,
|
|
59
76
|
dimensions.height,
|
|
60
77
|
sideOffset,
|
|
78
|
+
portalOffset,
|
|
61
79
|
]);
|
|
62
80
|
}
|
|
63
81
|
|
|
@@ -72,7 +90,7 @@ interface GetPositionArgs {
|
|
|
72
90
|
dimensions: DisplayMetrics;
|
|
73
91
|
triggerPosition: LayoutPosition;
|
|
74
92
|
contentLayout: LayoutRectangle;
|
|
75
|
-
insets
|
|
93
|
+
insets: SafeAreaInsets;
|
|
76
94
|
}
|
|
77
95
|
|
|
78
96
|
interface GetSidePositionArgs extends GetPositionArgs {
|
|
@@ -95,8 +113,7 @@ export const DEFAULT_POSITION: LayoutPosition = {
|
|
|
95
113
|
|
|
96
114
|
interface GetSideArgs {
|
|
97
115
|
preferredSide: "top" | "bottom";
|
|
98
|
-
|
|
99
|
-
insetBottom: number;
|
|
116
|
+
insets: SafeAreaInsets;
|
|
100
117
|
positionTop: number;
|
|
101
118
|
positionBottom: number;
|
|
102
119
|
contentLayout: LayoutRectangle;
|
|
@@ -105,29 +122,28 @@ interface GetSideArgs {
|
|
|
105
122
|
|
|
106
123
|
function getSide({
|
|
107
124
|
preferredSide,
|
|
108
|
-
|
|
109
|
-
insetBottom,
|
|
125
|
+
insets,
|
|
110
126
|
positionTop,
|
|
111
127
|
positionBottom,
|
|
112
128
|
contentLayout,
|
|
113
129
|
dimensions,
|
|
114
130
|
}: GetSideArgs) {
|
|
115
131
|
if (preferredSide === "bottom") {
|
|
116
|
-
const spaceBelow = dimensions.height -
|
|
132
|
+
const spaceBelow = dimensions.height - insets.bottom - positionBottom;
|
|
117
133
|
if (spaceBelow >= contentLayout.height) {
|
|
118
134
|
return "bottom";
|
|
119
135
|
}
|
|
120
|
-
const spaceAbove = positionTop -
|
|
136
|
+
const spaceAbove = positionTop - insets.top;
|
|
121
137
|
if (spaceAbove > spaceBelow) {
|
|
122
138
|
return "top";
|
|
123
139
|
}
|
|
124
140
|
return "bottom";
|
|
125
141
|
}
|
|
126
|
-
const spaceAbove = positionTop -
|
|
142
|
+
const spaceAbove = positionTop - insets.top;
|
|
127
143
|
if (spaceAbove >= contentLayout.height) {
|
|
128
144
|
return "top";
|
|
129
145
|
}
|
|
130
|
-
const spaceBelow = dimensions.height -
|
|
146
|
+
const spaceBelow = dimensions.height - insets.bottom - positionBottom;
|
|
131
147
|
if (spaceBelow > spaceAbove) {
|
|
132
148
|
return "bottom";
|
|
133
149
|
}
|
|
@@ -142,8 +158,6 @@ function getSidePosition({
|
|
|
142
158
|
insets,
|
|
143
159
|
dimensions,
|
|
144
160
|
}: GetSidePositionArgs) {
|
|
145
|
-
const insetTop = insets?.top ?? 0;
|
|
146
|
-
const insetBottom = insets?.bottom ?? 0;
|
|
147
161
|
const positionTop =
|
|
148
162
|
triggerPosition?.pageY - sideOffset - contentLayout.height;
|
|
149
163
|
const positionBottom =
|
|
@@ -151,8 +165,7 @@ function getSidePosition({
|
|
|
151
165
|
|
|
152
166
|
const side = getSide({
|
|
153
167
|
preferredSide,
|
|
154
|
-
|
|
155
|
-
insetBottom,
|
|
168
|
+
insets,
|
|
156
169
|
positionTop,
|
|
157
170
|
positionBottom,
|
|
158
171
|
contentLayout,
|
|
@@ -162,15 +175,15 @@ function getSidePosition({
|
|
|
162
175
|
if (side === "top") {
|
|
163
176
|
return {
|
|
164
177
|
top: Math.min(
|
|
165
|
-
Math.max(
|
|
166
|
-
dimensions.height -
|
|
178
|
+
Math.max(insets.top, positionTop),
|
|
179
|
+
dimensions.height - insets.bottom - contentLayout.height,
|
|
167
180
|
),
|
|
168
181
|
};
|
|
169
182
|
}
|
|
170
183
|
|
|
171
184
|
return {
|
|
172
185
|
top: Math.min(
|
|
173
|
-
dimensions.height -
|
|
186
|
+
dimensions.height - insets.bottom - contentLayout.height,
|
|
174
187
|
positionBottom,
|
|
175
188
|
),
|
|
176
189
|
};
|
|
@@ -189,9 +202,7 @@ function getAlignPosition({
|
|
|
189
202
|
insets,
|
|
190
203
|
dimensions,
|
|
191
204
|
}: GetAlignPositionArgs) {
|
|
192
|
-
const
|
|
193
|
-
const insetRight = insets?.right ?? 0;
|
|
194
|
-
const maxContentWidth = dimensions.width - insetLeft - insetRight;
|
|
205
|
+
const maxContentWidth = dimensions.width - insets.left - insets.right;
|
|
195
206
|
|
|
196
207
|
const contentWidth = Math.min(contentLayout.width, maxContentWidth);
|
|
197
208
|
|
|
@@ -201,25 +212,24 @@ function getAlignPosition({
|
|
|
201
212
|
triggerPosition.width,
|
|
202
213
|
contentWidth,
|
|
203
214
|
alignOffset,
|
|
204
|
-
|
|
205
|
-
insetRight,
|
|
215
|
+
insets,
|
|
206
216
|
dimensions,
|
|
207
217
|
);
|
|
208
218
|
|
|
209
219
|
const doesCollide =
|
|
210
|
-
left <
|
|
220
|
+
left < insets.left || left + contentWidth > dimensions.width - insets.right;
|
|
211
221
|
if (doesCollide) {
|
|
212
|
-
const spaceLeft = left -
|
|
213
|
-
const spaceRight = dimensions.width -
|
|
222
|
+
const spaceLeft = left - insets.left;
|
|
223
|
+
const spaceRight = dimensions.width - insets.right - (left + contentWidth);
|
|
214
224
|
|
|
215
225
|
if (spaceLeft > spaceRight && spaceLeft >= contentWidth) {
|
|
216
|
-
left =
|
|
226
|
+
left = insets.left;
|
|
217
227
|
} else if (spaceRight >= contentWidth) {
|
|
218
|
-
left = dimensions.width -
|
|
228
|
+
left = dimensions.width - insets.right - contentWidth;
|
|
219
229
|
} else {
|
|
220
230
|
const centeredPosition = Math.max(
|
|
221
|
-
|
|
222
|
-
(dimensions.width - contentWidth -
|
|
231
|
+
insets.left,
|
|
232
|
+
(dimensions.width - contentWidth - insets.right) / 2,
|
|
223
233
|
);
|
|
224
234
|
left = centeredPosition;
|
|
225
235
|
}
|
|
@@ -234,8 +244,7 @@ function getLeftPosition(
|
|
|
234
244
|
triggerWidth: number,
|
|
235
245
|
contentWidth: number,
|
|
236
246
|
alignOffset: number,
|
|
237
|
-
|
|
238
|
-
insetRight: number,
|
|
247
|
+
insets: SafeAreaInsets,
|
|
239
248
|
dimensions: DisplayMetrics,
|
|
240
249
|
) {
|
|
241
250
|
let left = 0;
|
|
@@ -249,8 +258,11 @@ function getLeftPosition(
|
|
|
249
258
|
left = triggerPageX + triggerWidth - contentWidth;
|
|
250
259
|
}
|
|
251
260
|
return Math.max(
|
|
252
|
-
|
|
253
|
-
Math.min(
|
|
261
|
+
insets.left,
|
|
262
|
+
Math.min(
|
|
263
|
+
left + alignOffset,
|
|
264
|
+
dimensions.width - contentWidth - insets.right,
|
|
265
|
+
),
|
|
254
266
|
);
|
|
255
267
|
}
|
|
256
268
|
|
package/src/themes/provider.tsx
CHANGED