@yahoo/uds-mobile 2.22.0 → 2.23.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.
- package/dist/bin/automated-config/dist/generated/generatedConfigs.mjs +3127 -452
- package/dist/bin/uds-mobile.mjs +7 -7
- package/dist/components/Select/Select.cjs +194 -0
- package/dist/components/Select/Select.d.cts +47 -0
- package/dist/components/Select/Select.d.cts.map +1 -0
- package/dist/components/Select/Select.d.ts +47 -0
- package/dist/components/Select/Select.d.ts.map +1 -0
- package/dist/components/Select/Select.js +194 -0
- package/dist/components/Select/Select.js.map +1 -0
- package/dist/components/Select/SelectContent.cjs +148 -0
- package/dist/components/Select/SelectContent.d.cts +31 -0
- package/dist/components/Select/SelectContent.d.cts.map +1 -0
- package/dist/components/Select/SelectContent.d.ts +31 -0
- package/dist/components/Select/SelectContent.d.ts.map +1 -0
- package/dist/components/Select/SelectContent.js +147 -0
- package/dist/components/Select/SelectContent.js.map +1 -0
- package/dist/components/Select/SelectItem.cjs +138 -0
- package/dist/components/Select/SelectItem.d.cts +24 -0
- package/dist/components/Select/SelectItem.d.cts.map +1 -0
- package/dist/components/Select/SelectItem.d.ts +24 -0
- package/dist/components/Select/SelectItem.d.ts.map +1 -0
- package/dist/components/Select/SelectItem.js +137 -0
- package/dist/components/Select/SelectItem.js.map +1 -0
- package/dist/components/Select/SelectTrigger.cjs +140 -0
- package/dist/components/Select/SelectTrigger.d.cts +13 -0
- package/dist/components/Select/SelectTrigger.d.cts.map +1 -0
- package/dist/components/Select/SelectTrigger.d.ts +13 -0
- package/dist/components/Select/SelectTrigger.d.ts.map +1 -0
- package/dist/components/Select/SelectTrigger.js +139 -0
- package/dist/components/Select/SelectTrigger.js.map +1 -0
- package/dist/components/Select/index.cjs +8 -0
- package/dist/components/Select/index.d.cts +5 -0
- package/dist/components/Select/index.d.ts +5 -0
- package/dist/components/Select/index.js +5 -0
- package/dist/components/Select/selectContext.cjs +22 -0
- package/dist/components/Select/selectContext.d.cts +12 -0
- package/dist/components/Select/selectContext.d.cts.map +1 -0
- package/dist/components/Select/selectContext.d.ts +12 -0
- package/dist/components/Select/selectContext.d.ts.map +1 -0
- package/dist/components/Select/selectContext.js +19 -0
- package/dist/components/Select/selectContext.js.map +1 -0
- package/dist/components/Select/selectItemTheme.cjs +39 -0
- package/dist/components/Select/selectItemTheme.d.cts +19 -0
- package/dist/components/Select/selectItemTheme.d.cts.map +1 -0
- package/dist/components/Select/selectItemTheme.d.ts +19 -0
- package/dist/components/Select/selectItemTheme.d.ts.map +1 -0
- package/dist/components/Select/selectItemTheme.js +39 -0
- package/dist/components/Select/selectItemTheme.js.map +1 -0
- package/dist/components/Select/types.cjs +1 -0
- package/dist/components/Select/types.d.cts +43 -0
- package/dist/components/Select/types.d.cts.map +1 -0
- package/dist/components/Select/types.d.ts +43 -0
- package/dist/components/Select/types.d.ts.map +1 -0
- package/dist/components/Select/types.js +1 -0
- package/dist/components/internal/Overlay/index.cjs +2 -0
- package/dist/components/internal/Overlay/index.d.cts +2 -1
- package/dist/components/internal/Overlay/index.d.ts +2 -1
- package/dist/components/internal/Overlay/index.js +2 -1
- package/dist/components/internal/Overlay/measureTrigger.cjs +35 -0
- package/dist/components/internal/Overlay/measureTrigger.d.cts +9 -0
- package/dist/components/internal/Overlay/measureTrigger.d.cts.map +1 -0
- package/dist/components/internal/Overlay/measureTrigger.d.ts +9 -0
- package/dist/components/internal/Overlay/measureTrigger.d.ts.map +1 -0
- package/dist/components/internal/Overlay/measureTrigger.js +36 -0
- package/dist/components/internal/Overlay/measureTrigger.js.map +1 -0
- package/dist/jest/mocks/styles.cjs +47 -1
- package/dist/jest/mocks/styles.d.cts +5 -2
- package/dist/jest/mocks/styles.d.cts.map +1 -1
- package/dist/jest/mocks/styles.d.ts +5 -2
- package/dist/jest/mocks/styles.d.ts.map +1 -1
- package/dist/jest/mocks/styles.js +45 -2
- package/dist/jest/mocks/styles.js.map +1 -1
- package/dist/types/dist/index.d.cts +28 -1
- package/dist/types/dist/index.d.cts.map +1 -1
- package/dist/types/dist/index.d.ts +28 -1
- package/dist/types/dist/index.d.ts.map +1 -1
- package/generated/styles.cjs +125 -0
- package/generated/styles.d.ts +39 -0
- package/generated/styles.mjs +125 -0
- package/generated/unistyles.d.ts +108 -8
- package/package.json +11 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
import { SelectContentSize, SelectContentVariant } from "./types.cjs";
|
|
3
|
+
import * as _$react from "react";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
6
|
+
|
|
7
|
+
//#region src/components/Select/SelectContent.d.ts
|
|
8
|
+
interface SelectContentProps {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
size?: SelectContentSize;
|
|
11
|
+
variant?: SelectContentVariant;
|
|
12
|
+
/** When true, the panel stays open when the user taps outside. */
|
|
13
|
+
keepOpenOnInteractOutside?: boolean;
|
|
14
|
+
/** Maximum height of the options list in pixels. @default 240 */
|
|
15
|
+
maxHeight?: number;
|
|
16
|
+
/** Distance between the trigger and the content panel. @default 4 */
|
|
17
|
+
gutter?: number;
|
|
18
|
+
/** When true, the content panel matches the trigger width. @default true */
|
|
19
|
+
sameWidth?: boolean;
|
|
20
|
+
style?: StyleProp<ViewStyle>;
|
|
21
|
+
testID?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* **▾ Select content panel**
|
|
25
|
+
*
|
|
26
|
+
* Floating listbox container for {@link SelectItem} options.
|
|
27
|
+
*/
|
|
28
|
+
declare const SelectContent: _$react.NamedExoticComponent<SelectContentProps>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { SelectContent, type SelectContentProps };
|
|
31
|
+
//# sourceMappingURL=SelectContent.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectContent.d.cts","names":[],"sources":["../../../src/components/Select/SelectContent.tsx"],"mappings":";;;;;;;UAmCU,kBAAA;EACR,QAAA,GAAW,SAAA;EACX,IAAA,GAAO,iBAAA;EACP,OAAA,GAAU,oBAAA;EAHgB;EAK1B,yBAAA;EAJW;EAMX,SAAA;EAJU;EAMV,MAAA;EAGQ;EADR,SAAA;EACA,KAAA,GAAQ,SAAA,CAAU,SAAA;EAClB,MAAA;AAAA;;;;;;cAQI,aAAA,EAAa,OAAA,CAAA,oBAAA,CAAA,kBAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
import { SelectContentSize, SelectContentVariant } from "./types.js";
|
|
3
|
+
import * as _$react from "react";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
6
|
+
|
|
7
|
+
//#region src/components/Select/SelectContent.d.ts
|
|
8
|
+
interface SelectContentProps {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
size?: SelectContentSize;
|
|
11
|
+
variant?: SelectContentVariant;
|
|
12
|
+
/** When true, the panel stays open when the user taps outside. */
|
|
13
|
+
keepOpenOnInteractOutside?: boolean;
|
|
14
|
+
/** Maximum height of the options list in pixels. @default 240 */
|
|
15
|
+
maxHeight?: number;
|
|
16
|
+
/** Distance between the trigger and the content panel. @default 4 */
|
|
17
|
+
gutter?: number;
|
|
18
|
+
/** When true, the content panel matches the trigger width. @default true */
|
|
19
|
+
sameWidth?: boolean;
|
|
20
|
+
style?: StyleProp<ViewStyle>;
|
|
21
|
+
testID?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* **▾ Select content panel**
|
|
25
|
+
*
|
|
26
|
+
* Floating listbox container for {@link SelectItem} options.
|
|
27
|
+
*/
|
|
28
|
+
declare const SelectContent: _$react.NamedExoticComponent<SelectContentProps>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { SelectContent, type SelectContentProps };
|
|
31
|
+
//# sourceMappingURL=SelectContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectContent.d.ts","names":[],"sources":["../../../src/components/Select/SelectContent.tsx"],"mappings":";;;;;;;UAmCU,kBAAA;EACR,QAAA,GAAW,SAAA;EACX,IAAA,GAAO,iBAAA;EACP,OAAA,GAAU,oBAAA;EAHgB;EAK1B,yBAAA;EAJW;EAMX,SAAA;EAJU;EAMV,MAAA;EAGQ;EADR,SAAA;EACA,KAAA,GAAQ,SAAA,CAAU,SAAA;EAClB,MAAA;AAAA;;;;;;cAQI,aAAA,EAAa,OAAA,CAAA,oBAAA,CAAA,kBAAA"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
|
|
2
|
+
import { VStack } from "../VStack.js";
|
|
3
|
+
import { useAnchoredPosition } from "../internal/Overlay/useAnchoredPosition.js";
|
|
4
|
+
import { PopoverPortalLayer } from "../Popover/PopoverPortalLayer.js";
|
|
5
|
+
import { useSelectContext } from "./selectContext.js";
|
|
6
|
+
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|
7
|
+
import { ScrollView, StyleSheet, View } from "react-native";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { selectContentStyles } from "../../../generated/styles";
|
|
10
|
+
import Animated, { Easing, useAnimatedStyle, useDerivedValue, withTiming } from "react-native-reanimated";
|
|
11
|
+
//#region src/components/Select/SelectContent.tsx
|
|
12
|
+
const DEFAULT_OFFSET = 4;
|
|
13
|
+
const DEFAULT_MAX_HEIGHT = 240;
|
|
14
|
+
const ANIMATION_DURATION = 200;
|
|
15
|
+
const OFFSCREEN_REGISTRY_STYLE = StyleSheet.create({ registry: {
|
|
16
|
+
position: "absolute",
|
|
17
|
+
top: 0,
|
|
18
|
+
left: 0,
|
|
19
|
+
width: 1,
|
|
20
|
+
height: 1,
|
|
21
|
+
opacity: 0,
|
|
22
|
+
overflow: "hidden",
|
|
23
|
+
zIndex: -1
|
|
24
|
+
} });
|
|
25
|
+
/**
|
|
26
|
+
* **▾ Select content panel**
|
|
27
|
+
*
|
|
28
|
+
* Floating listbox container for {@link SelectItem} options.
|
|
29
|
+
*/
|
|
30
|
+
const SelectContent = memo(function SelectContent({ children, size: _size = "default", variant: _variant = "default", keepOpenOnInteractOutside = false, maxHeight = DEFAULT_MAX_HEIGHT, gutter = DEFAULT_OFFSET, sameWidth = true, style, testID }) {
|
|
31
|
+
const { open, setOpen, triggerRect, reduceMotion } = useSelectContext();
|
|
32
|
+
const [contentSize, setContentSize] = useState({
|
|
33
|
+
width: 0,
|
|
34
|
+
height: 0
|
|
35
|
+
});
|
|
36
|
+
const [shouldRender, setShouldRender] = useState(open);
|
|
37
|
+
const dismiss = useCallback(() => {
|
|
38
|
+
if (keepOpenOnInteractOutside) return;
|
|
39
|
+
setOpen(false);
|
|
40
|
+
}, [keepOpenOnInteractOutside, setOpen]);
|
|
41
|
+
const { contentStyle, anchorReady, maxWidth: positionedMaxWidth } = useAnchoredPosition({
|
|
42
|
+
triggerRect,
|
|
43
|
+
contentSize,
|
|
44
|
+
placement: "bottom",
|
|
45
|
+
offset: gutter,
|
|
46
|
+
sameWidth,
|
|
47
|
+
width: sameWidth ? "trigger" : "content",
|
|
48
|
+
avoidCollisions: true,
|
|
49
|
+
collisionPadding: 12
|
|
50
|
+
});
|
|
51
|
+
const isPositionedOpen = open && anchorReady && contentSize.height > 0;
|
|
52
|
+
const progress = useDerivedValue(() => withTiming(isPositionedOpen ? 1 : 0, {
|
|
53
|
+
duration: reduceMotion ? 0 : ANIMATION_DURATION,
|
|
54
|
+
easing: Easing.out(Easing.ease)
|
|
55
|
+
}), [isPositionedOpen, reduceMotion]);
|
|
56
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
57
|
+
opacity: progress.value,
|
|
58
|
+
transform: [{ scale: .97 + progress.value * .03 }, { translateY: (1 - progress.value) * 8 }]
|
|
59
|
+
}));
|
|
60
|
+
const handleLayout = useCallback((event) => {
|
|
61
|
+
const { width, height } = event.nativeEvent.layout;
|
|
62
|
+
setContentSize({
|
|
63
|
+
width,
|
|
64
|
+
height
|
|
65
|
+
});
|
|
66
|
+
}, []);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (open) {
|
|
69
|
+
setShouldRender(true);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (reduceMotion) {
|
|
73
|
+
setShouldRender(false);
|
|
74
|
+
setContentSize({
|
|
75
|
+
width: 0,
|
|
76
|
+
height: 0
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const timeout = setTimeout(() => {
|
|
81
|
+
setShouldRender(false);
|
|
82
|
+
setContentSize({
|
|
83
|
+
width: 0,
|
|
84
|
+
height: 0
|
|
85
|
+
});
|
|
86
|
+
}, ANIMATION_DURATION);
|
|
87
|
+
return () => clearTimeout(timeout);
|
|
88
|
+
}, [open, reduceMotion]);
|
|
89
|
+
selectContentStyles.useVariants({});
|
|
90
|
+
const panelStyle = useMemo(() => StyleSheet.flatten([
|
|
91
|
+
selectContentStyles.root,
|
|
92
|
+
{
|
|
93
|
+
maxHeight,
|
|
94
|
+
maxWidth: positionedMaxWidth > 0 ? positionedMaxWidth : void 0,
|
|
95
|
+
overflow: "hidden",
|
|
96
|
+
zIndex: 1
|
|
97
|
+
},
|
|
98
|
+
style
|
|
99
|
+
]), [
|
|
100
|
+
maxHeight,
|
|
101
|
+
positionedMaxWidth,
|
|
102
|
+
selectContentStyles.root,
|
|
103
|
+
style
|
|
104
|
+
]);
|
|
105
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [!open ? /* @__PURE__ */ jsx(View, {
|
|
106
|
+
accessibilityElementsHidden: true,
|
|
107
|
+
importantForAccessibility: "no-hide-descendants",
|
|
108
|
+
pointerEvents: "none",
|
|
109
|
+
style: OFFSCREEN_REGISTRY_STYLE.registry,
|
|
110
|
+
children
|
|
111
|
+
}) : null, open && shouldRender ? /* @__PURE__ */ jsx(PopoverPortalLayer, {
|
|
112
|
+
open,
|
|
113
|
+
dismissible: !keepOpenOnInteractOutside,
|
|
114
|
+
onDismiss: dismiss,
|
|
115
|
+
children: () => /* @__PURE__ */ jsx(Animated.View, {
|
|
116
|
+
testID,
|
|
117
|
+
style: [
|
|
118
|
+
contentStyle,
|
|
119
|
+
animatedStyle,
|
|
120
|
+
{
|
|
121
|
+
overflow: "visible",
|
|
122
|
+
zIndex: 1e3
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
onLayout: handleLayout,
|
|
126
|
+
accessibilityRole: "menu",
|
|
127
|
+
children: /* @__PURE__ */ jsx(View, {
|
|
128
|
+
style: panelStyle,
|
|
129
|
+
children: /* @__PURE__ */ jsx(ScrollView, {
|
|
130
|
+
keyboardShouldPersistTaps: "handled",
|
|
131
|
+
nestedScrollEnabled: true,
|
|
132
|
+
style: { maxHeight },
|
|
133
|
+
children: /* @__PURE__ */ jsx(VStack, {
|
|
134
|
+
alignItems: "stretch",
|
|
135
|
+
justifyContent: "flex-start",
|
|
136
|
+
children
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
}) : null] });
|
|
142
|
+
});
|
|
143
|
+
SelectContent.displayName = "SelectContent";
|
|
144
|
+
//#endregion
|
|
145
|
+
export { SelectContent };
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=SelectContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectContent.js","names":["RNScrollView"],"sources":["../../../src/components/Select/SelectContent.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { memo, useCallback, useEffect, useMemo, useState } from 'react';\nimport type { LayoutChangeEvent, StyleProp, ViewStyle } from 'react-native';\nimport { ScrollView as RNScrollView, StyleSheet, View } from 'react-native';\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useDerivedValue,\n withTiming,\n} from 'react-native-reanimated';\n\nimport { selectContentStyles } from '../../../generated/styles';\nimport { useAnchoredPosition } from '../internal/Overlay';\nimport { PopoverPortalLayer } from '../Popover/PopoverPortalLayer';\nimport { VStack } from '../VStack';\nimport { useSelectContext } from './selectContext';\nimport type { SelectContentSize, SelectContentVariant } from './types';\n\nconst DEFAULT_OFFSET = 4;\nconst DEFAULT_MAX_HEIGHT = 240;\nconst ANIMATION_DURATION = 200;\n\nconst OFFSCREEN_REGISTRY_STYLE = StyleSheet.create({\n registry: {\n position: 'absolute',\n top: 0,\n left: 0,\n width: 1,\n height: 1,\n opacity: 0,\n overflow: 'hidden',\n zIndex: -1,\n },\n});\n\ninterface SelectContentProps {\n children?: ReactNode;\n size?: SelectContentSize;\n variant?: SelectContentVariant;\n /** When true, the panel stays open when the user taps outside. */\n keepOpenOnInteractOutside?: boolean;\n /** Maximum height of the options list in pixels. @default 240 */\n maxHeight?: number;\n /** Distance between the trigger and the content panel. @default 4 */\n gutter?: number;\n /** When true, the content panel matches the trigger width. @default true */\n sameWidth?: boolean;\n style?: StyleProp<ViewStyle>;\n testID?: string;\n}\n\n/**\n * **▾ Select content panel**\n *\n * Floating listbox container for {@link SelectItem} options.\n */\nconst SelectContent = memo(function SelectContent({\n children,\n size: _size = 'default',\n variant: _variant = 'default',\n keepOpenOnInteractOutside = false,\n maxHeight = DEFAULT_MAX_HEIGHT,\n gutter = DEFAULT_OFFSET,\n sameWidth = true,\n style,\n testID,\n}: SelectContentProps) {\n const { open, setOpen, triggerRect, reduceMotion } = useSelectContext();\n const [contentSize, setContentSize] = useState({ width: 0, height: 0 });\n const [shouldRender, setShouldRender] = useState(open);\n\n const dismiss = useCallback(() => {\n if (keepOpenOnInteractOutside) {\n return;\n }\n\n setOpen(false);\n }, [keepOpenOnInteractOutside, setOpen]);\n\n const {\n contentStyle,\n anchorReady,\n maxWidth: positionedMaxWidth,\n } = useAnchoredPosition({\n triggerRect,\n contentSize,\n placement: 'bottom',\n offset: gutter,\n sameWidth,\n width: sameWidth ? 'trigger' : 'content',\n avoidCollisions: true,\n collisionPadding: 12,\n });\n\n const isPositionedOpen = open && anchorReady && contentSize.height > 0;\n const progress = useDerivedValue(\n () =>\n withTiming(isPositionedOpen ? 1 : 0, {\n duration: reduceMotion ? 0 : ANIMATION_DURATION,\n easing: Easing.out(Easing.ease),\n }),\n [isPositionedOpen, reduceMotion],\n );\n\n const animatedStyle = useAnimatedStyle(() => ({\n opacity: progress.value,\n transform: [{ scale: 0.97 + progress.value * 0.03 }, { translateY: (1 - progress.value) * 8 }],\n }));\n\n const handleLayout = useCallback((event: LayoutChangeEvent) => {\n const { width, height } = event.nativeEvent.layout;\n setContentSize({ width, height });\n }, []);\n\n useEffect(() => {\n if (open) {\n setShouldRender(true);\n return;\n }\n\n if (reduceMotion) {\n setShouldRender(false);\n setContentSize({ width: 0, height: 0 });\n return;\n }\n\n const timeout = setTimeout(() => {\n setShouldRender(false);\n setContentSize({ width: 0, height: 0 });\n }, ANIMATION_DURATION);\n\n return () => clearTimeout(timeout);\n }, [open, reduceMotion]);\n\n selectContentStyles.useVariants({});\n\n const panelStyle = useMemo(\n () =>\n StyleSheet.flatten([\n selectContentStyles.root,\n {\n maxHeight,\n maxWidth: positionedMaxWidth > 0 ? positionedMaxWidth : undefined,\n overflow: 'hidden',\n zIndex: 1,\n },\n style,\n ]) as ViewStyle,\n [maxHeight, positionedMaxWidth, selectContentStyles.root, style],\n );\n\n return (\n <>\n {!open ? (\n <View\n accessibilityElementsHidden\n importantForAccessibility=\"no-hide-descendants\"\n pointerEvents=\"none\"\n style={OFFSCREEN_REGISTRY_STYLE.registry}\n >\n {children}\n </View>\n ) : null}\n\n {open && shouldRender ? (\n <PopoverPortalLayer\n open={open}\n dismissible={!keepOpenOnInteractOutside}\n onDismiss={dismiss}\n >\n {() => (\n <Animated.View\n testID={testID}\n style={[contentStyle, animatedStyle, { overflow: 'visible', zIndex: 1000 }]}\n onLayout={handleLayout}\n accessibilityRole=\"menu\"\n >\n <View style={panelStyle}>\n <RNScrollView\n keyboardShouldPersistTaps=\"handled\"\n nestedScrollEnabled\n style={{ maxHeight }}\n >\n <VStack alignItems=\"stretch\" justifyContent=\"flex-start\">\n {children}\n </VStack>\n </RNScrollView>\n </View>\n </Animated.View>\n )}\n </PopoverPortalLayer>\n ) : null}\n </>\n );\n});\n\nSelectContent.displayName = 'SelectContent';\n\nexport { SelectContent, type SelectContentProps };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
|
|
4
|
+
const require_components_HStack = require("../HStack.cjs");
|
|
5
|
+
const require_components_IconSlot = require("../IconSlot.cjs");
|
|
6
|
+
const require_components_Select_selectContext = require("./selectContext.cjs");
|
|
7
|
+
const require_components_Select_selectItemTheme = require("./selectItemTheme.cjs");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let react_native = require("react-native");
|
|
10
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
11
|
+
let react_native_unistyles = require("react-native-unistyles");
|
|
12
|
+
let react_native_reanimated = require("react-native-reanimated");
|
|
13
|
+
react_native_reanimated = require_runtime.__toESM(react_native_reanimated);
|
|
14
|
+
//#region src/components/Select/SelectItem.tsx
|
|
15
|
+
/**
|
|
16
|
+
* **▾ Select item**
|
|
17
|
+
*
|
|
18
|
+
* A single selectable option inside {@link SelectContent}.
|
|
19
|
+
*/
|
|
20
|
+
const SelectItem = (0, react.memo)(function SelectItem({ value, disabled, children, style, testID }) {
|
|
21
|
+
const { value: selectedValue, setValue, setOpen, open, registerItem, unregisterItem, highlightedValue, setHighlightedValue, reduceMotion } = require_components_Select_selectContext.useSelectContext();
|
|
22
|
+
const { theme } = (0, react_native_unistyles.useUnistyles)();
|
|
23
|
+
const [isPressed, setIsPressed] = (0, react.useState)(false);
|
|
24
|
+
const label = (0, react.useMemo)(() => {
|
|
25
|
+
if (typeof children === "string" || typeof children === "number") return String(children);
|
|
26
|
+
return value;
|
|
27
|
+
}, [children, value]);
|
|
28
|
+
(0, react.useEffect)(() => {
|
|
29
|
+
registerItem(value, label);
|
|
30
|
+
return () => unregisterItem(value);
|
|
31
|
+
}, [
|
|
32
|
+
label,
|
|
33
|
+
registerItem,
|
|
34
|
+
unregisterItem,
|
|
35
|
+
value
|
|
36
|
+
]);
|
|
37
|
+
const isSelected = selectedValue === value;
|
|
38
|
+
const interaction = require_components_Select_selectItemTheme.resolveSelectItemInteractionState({
|
|
39
|
+
isPressed,
|
|
40
|
+
isHighlighted: highlightedValue === value
|
|
41
|
+
});
|
|
42
|
+
const rootStyle = (0, react.useMemo)(() => [
|
|
43
|
+
require_components_Select_selectItemTheme.getMergedSelectItemLayerStyle(theme, "root", interaction, isSelected),
|
|
44
|
+
{
|
|
45
|
+
flexDirection: "row",
|
|
46
|
+
alignItems: "center",
|
|
47
|
+
justifyContent: "space-between",
|
|
48
|
+
width: "100%",
|
|
49
|
+
opacity: disabled ? .5 : 1
|
|
50
|
+
},
|
|
51
|
+
style
|
|
52
|
+
], [
|
|
53
|
+
disabled,
|
|
54
|
+
interaction,
|
|
55
|
+
isSelected,
|
|
56
|
+
style,
|
|
57
|
+
theme
|
|
58
|
+
]);
|
|
59
|
+
const textStyle = (0, react.useMemo)(() => require_components_Select_selectItemTheme.getMergedSelectItemLayerStyle(theme, "text", interaction, isSelected), [
|
|
60
|
+
interaction,
|
|
61
|
+
isSelected,
|
|
62
|
+
theme
|
|
63
|
+
]);
|
|
64
|
+
const endIconStyle = (0, react.useMemo)(() => require_components_Select_selectItemTheme.getMergedSelectItemLayerStyle(theme, "endIcon", interaction, isSelected), [
|
|
65
|
+
interaction,
|
|
66
|
+
isSelected,
|
|
67
|
+
theme
|
|
68
|
+
]);
|
|
69
|
+
const checkScale = (0, react_native_reanimated.useDerivedValue)(() => (0, react_native_reanimated.withTiming)(isSelected ? 1 : 0, {
|
|
70
|
+
duration: reduceMotion ? 0 : 120,
|
|
71
|
+
easing: react_native_reanimated.Easing.out(react_native_reanimated.Easing.ease)
|
|
72
|
+
}), [isSelected, reduceMotion]);
|
|
73
|
+
const checkAnimatedStyle = (0, react_native_reanimated.useAnimatedStyle)(() => ({
|
|
74
|
+
opacity: checkScale.value,
|
|
75
|
+
transform: [{ scale: .7 + checkScale.value * .3 }]
|
|
76
|
+
}));
|
|
77
|
+
const handlePress = (0, react.useCallback)(() => {
|
|
78
|
+
if (disabled) return;
|
|
79
|
+
setValue(value);
|
|
80
|
+
setOpen(false);
|
|
81
|
+
setHighlightedValue(null);
|
|
82
|
+
}, [
|
|
83
|
+
disabled,
|
|
84
|
+
setHighlightedValue,
|
|
85
|
+
setOpen,
|
|
86
|
+
setValue,
|
|
87
|
+
value
|
|
88
|
+
]);
|
|
89
|
+
const handlePressIn = (0, react.useCallback)(() => {
|
|
90
|
+
if (disabled) return;
|
|
91
|
+
setIsPressed(true);
|
|
92
|
+
setHighlightedValue(value);
|
|
93
|
+
}, [
|
|
94
|
+
disabled,
|
|
95
|
+
setHighlightedValue,
|
|
96
|
+
value
|
|
97
|
+
]);
|
|
98
|
+
const handlePressOut = (0, react.useCallback)(() => {
|
|
99
|
+
setIsPressed(false);
|
|
100
|
+
}, []);
|
|
101
|
+
if (!open) return null;
|
|
102
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.Pressable, {
|
|
103
|
+
testID,
|
|
104
|
+
disabled,
|
|
105
|
+
onPress: handlePress,
|
|
106
|
+
onPressIn: handlePressIn,
|
|
107
|
+
onPressOut: handlePressOut,
|
|
108
|
+
style: rootStyle,
|
|
109
|
+
accessibilityRole: "menuitem",
|
|
110
|
+
accessibilityState: {
|
|
111
|
+
disabled: !!disabled,
|
|
112
|
+
selected: isSelected
|
|
113
|
+
},
|
|
114
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_HStack.HStack, {
|
|
115
|
+
columnGap: "2",
|
|
116
|
+
alignItems: "center",
|
|
117
|
+
justifyContent: "flex-start",
|
|
118
|
+
style: { flex: 1 },
|
|
119
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.Text, {
|
|
120
|
+
style: textStyle,
|
|
121
|
+
numberOfLines: 1,
|
|
122
|
+
children
|
|
123
|
+
})
|
|
124
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_reanimated.default.View, {
|
|
125
|
+
style: checkAnimatedStyle,
|
|
126
|
+
pointerEvents: "none",
|
|
127
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_IconSlot.IconSlot, {
|
|
128
|
+
icon: "Check",
|
|
129
|
+
size: "sm",
|
|
130
|
+
variant: "fill",
|
|
131
|
+
style: endIconStyle
|
|
132
|
+
})
|
|
133
|
+
})]
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
SelectItem.displayName = "SelectItem";
|
|
137
|
+
//#endregion
|
|
138
|
+
exports.SelectItem = SelectItem;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
import * as _$react from "react";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
5
|
+
|
|
6
|
+
//#region src/components/Select/SelectItem.d.ts
|
|
7
|
+
interface SelectItemProps {
|
|
8
|
+
/** Value submitted when this option is selected. */
|
|
9
|
+
value: string;
|
|
10
|
+
/** Whether this option is disabled. */
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
style?: StyleProp<ViewStyle>;
|
|
14
|
+
testID?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* **▾ Select item**
|
|
18
|
+
*
|
|
19
|
+
* A single selectable option inside {@link SelectContent}.
|
|
20
|
+
*/
|
|
21
|
+
declare const SelectItem: _$react.NamedExoticComponent<SelectItemProps>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { SelectItem, type SelectItemProps };
|
|
24
|
+
//# sourceMappingURL=SelectItem.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectItem.d.cts","names":[],"sources":["../../../src/components/Select/SelectItem.tsx"],"mappings":";;;;;;UAqBU,eAAA;;EAER,KAAA;EAFQ;EAIR,QAAA;EACA,QAAA,GAAW,SAAA;EACX,KAAA,GAAQ,SAAA,CAAU,SAAA;EAClB,MAAA;AAAA;;;;;;cAQI,UAAA,EAAU,OAAA,CAAA,oBAAA,CAAA,eAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
import * as _$react from "react";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
5
|
+
|
|
6
|
+
//#region src/components/Select/SelectItem.d.ts
|
|
7
|
+
interface SelectItemProps {
|
|
8
|
+
/** Value submitted when this option is selected. */
|
|
9
|
+
value: string;
|
|
10
|
+
/** Whether this option is disabled. */
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
style?: StyleProp<ViewStyle>;
|
|
14
|
+
testID?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* **▾ Select item**
|
|
18
|
+
*
|
|
19
|
+
* A single selectable option inside {@link SelectContent}.
|
|
20
|
+
*/
|
|
21
|
+
declare const SelectItem: _$react.NamedExoticComponent<SelectItemProps>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { SelectItem, type SelectItemProps };
|
|
24
|
+
//# sourceMappingURL=SelectItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectItem.d.ts","names":[],"sources":["../../../src/components/Select/SelectItem.tsx"],"mappings":";;;;;;UAqBU,eAAA;;EAER,KAAA;EAFQ;EAIR,QAAA;EACA,QAAA,GAAW,SAAA;EACX,KAAA,GAAQ,SAAA,CAAU,SAAA;EAClB,MAAA;AAAA;;;;;;cAQI,UAAA,EAAU,OAAA,CAAA,oBAAA,CAAA,eAAA"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
|
|
2
|
+
import { HStack } from "../HStack.js";
|
|
3
|
+
import { IconSlot } from "../IconSlot.js";
|
|
4
|
+
import { useSelectContext } from "./selectContext.js";
|
|
5
|
+
import { getMergedSelectItemLayerStyle, resolveSelectItemInteractionState } from "./selectItemTheme.js";
|
|
6
|
+
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|
7
|
+
import { Pressable, Text } from "react-native";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { useUnistyles } from "react-native-unistyles";
|
|
10
|
+
import Animated, { Easing, useAnimatedStyle, useDerivedValue, withTiming } from "react-native-reanimated";
|
|
11
|
+
//#region src/components/Select/SelectItem.tsx
|
|
12
|
+
/**
|
|
13
|
+
* **▾ Select item**
|
|
14
|
+
*
|
|
15
|
+
* A single selectable option inside {@link SelectContent}.
|
|
16
|
+
*/
|
|
17
|
+
const SelectItem = memo(function SelectItem({ value, disabled, children, style, testID }) {
|
|
18
|
+
const { value: selectedValue, setValue, setOpen, open, registerItem, unregisterItem, highlightedValue, setHighlightedValue, reduceMotion } = useSelectContext();
|
|
19
|
+
const { theme } = useUnistyles();
|
|
20
|
+
const [isPressed, setIsPressed] = useState(false);
|
|
21
|
+
const label = useMemo(() => {
|
|
22
|
+
if (typeof children === "string" || typeof children === "number") return String(children);
|
|
23
|
+
return value;
|
|
24
|
+
}, [children, value]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
registerItem(value, label);
|
|
27
|
+
return () => unregisterItem(value);
|
|
28
|
+
}, [
|
|
29
|
+
label,
|
|
30
|
+
registerItem,
|
|
31
|
+
unregisterItem,
|
|
32
|
+
value
|
|
33
|
+
]);
|
|
34
|
+
const isSelected = selectedValue === value;
|
|
35
|
+
const interaction = resolveSelectItemInteractionState({
|
|
36
|
+
isPressed,
|
|
37
|
+
isHighlighted: highlightedValue === value
|
|
38
|
+
});
|
|
39
|
+
const rootStyle = useMemo(() => [
|
|
40
|
+
getMergedSelectItemLayerStyle(theme, "root", interaction, isSelected),
|
|
41
|
+
{
|
|
42
|
+
flexDirection: "row",
|
|
43
|
+
alignItems: "center",
|
|
44
|
+
justifyContent: "space-between",
|
|
45
|
+
width: "100%",
|
|
46
|
+
opacity: disabled ? .5 : 1
|
|
47
|
+
},
|
|
48
|
+
style
|
|
49
|
+
], [
|
|
50
|
+
disabled,
|
|
51
|
+
interaction,
|
|
52
|
+
isSelected,
|
|
53
|
+
style,
|
|
54
|
+
theme
|
|
55
|
+
]);
|
|
56
|
+
const textStyle = useMemo(() => getMergedSelectItemLayerStyle(theme, "text", interaction, isSelected), [
|
|
57
|
+
interaction,
|
|
58
|
+
isSelected,
|
|
59
|
+
theme
|
|
60
|
+
]);
|
|
61
|
+
const endIconStyle = useMemo(() => getMergedSelectItemLayerStyle(theme, "endIcon", interaction, isSelected), [
|
|
62
|
+
interaction,
|
|
63
|
+
isSelected,
|
|
64
|
+
theme
|
|
65
|
+
]);
|
|
66
|
+
const checkScale = useDerivedValue(() => withTiming(isSelected ? 1 : 0, {
|
|
67
|
+
duration: reduceMotion ? 0 : 120,
|
|
68
|
+
easing: Easing.out(Easing.ease)
|
|
69
|
+
}), [isSelected, reduceMotion]);
|
|
70
|
+
const checkAnimatedStyle = useAnimatedStyle(() => ({
|
|
71
|
+
opacity: checkScale.value,
|
|
72
|
+
transform: [{ scale: .7 + checkScale.value * .3 }]
|
|
73
|
+
}));
|
|
74
|
+
const handlePress = useCallback(() => {
|
|
75
|
+
if (disabled) return;
|
|
76
|
+
setValue(value);
|
|
77
|
+
setOpen(false);
|
|
78
|
+
setHighlightedValue(null);
|
|
79
|
+
}, [
|
|
80
|
+
disabled,
|
|
81
|
+
setHighlightedValue,
|
|
82
|
+
setOpen,
|
|
83
|
+
setValue,
|
|
84
|
+
value
|
|
85
|
+
]);
|
|
86
|
+
const handlePressIn = useCallback(() => {
|
|
87
|
+
if (disabled) return;
|
|
88
|
+
setIsPressed(true);
|
|
89
|
+
setHighlightedValue(value);
|
|
90
|
+
}, [
|
|
91
|
+
disabled,
|
|
92
|
+
setHighlightedValue,
|
|
93
|
+
value
|
|
94
|
+
]);
|
|
95
|
+
const handlePressOut = useCallback(() => {
|
|
96
|
+
setIsPressed(false);
|
|
97
|
+
}, []);
|
|
98
|
+
if (!open) return null;
|
|
99
|
+
return /* @__PURE__ */ jsxs(Pressable, {
|
|
100
|
+
testID,
|
|
101
|
+
disabled,
|
|
102
|
+
onPress: handlePress,
|
|
103
|
+
onPressIn: handlePressIn,
|
|
104
|
+
onPressOut: handlePressOut,
|
|
105
|
+
style: rootStyle,
|
|
106
|
+
accessibilityRole: "menuitem",
|
|
107
|
+
accessibilityState: {
|
|
108
|
+
disabled: !!disabled,
|
|
109
|
+
selected: isSelected
|
|
110
|
+
},
|
|
111
|
+
children: [/* @__PURE__ */ jsx(HStack, {
|
|
112
|
+
columnGap: "2",
|
|
113
|
+
alignItems: "center",
|
|
114
|
+
justifyContent: "flex-start",
|
|
115
|
+
style: { flex: 1 },
|
|
116
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
117
|
+
style: textStyle,
|
|
118
|
+
numberOfLines: 1,
|
|
119
|
+
children
|
|
120
|
+
})
|
|
121
|
+
}), /* @__PURE__ */ jsx(Animated.View, {
|
|
122
|
+
style: checkAnimatedStyle,
|
|
123
|
+
pointerEvents: "none",
|
|
124
|
+
children: /* @__PURE__ */ jsx(IconSlot, {
|
|
125
|
+
icon: "Check",
|
|
126
|
+
size: "sm",
|
|
127
|
+
variant: "fill",
|
|
128
|
+
style: endIconStyle
|
|
129
|
+
})
|
|
130
|
+
})]
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
SelectItem.displayName = "SelectItem";
|
|
134
|
+
//#endregion
|
|
135
|
+
export { SelectItem };
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=SelectItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectItem.js","names":["RNPressable","RNText"],"sources":["../../../src/components/Select/SelectItem.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { memo, useCallback, useEffect, useMemo, useState } from 'react';\nimport type { StyleProp, ViewStyle } from 'react-native';\nimport { Pressable as RNPressable, Text as RNText } from 'react-native';\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useDerivedValue,\n withTiming,\n} from 'react-native-reanimated';\n// eslint-disable-next-line uds/no-use-unistyles -- selectItem selected state uses theme paths\nimport { useUnistyles } from 'react-native-unistyles';\n\nimport { HStack } from '../HStack';\nimport { IconSlot } from '../IconSlot';\nimport { useSelectContext } from './selectContext';\nimport {\n getMergedSelectItemLayerStyle,\n resolveSelectItemInteractionState,\n} from './selectItemTheme';\n\ninterface SelectItemProps {\n /** Value submitted when this option is selected. */\n value: string;\n /** Whether this option is disabled. */\n disabled?: boolean;\n children?: ReactNode;\n style?: StyleProp<ViewStyle>;\n testID?: string;\n}\n\n/**\n * **▾ Select item**\n *\n * A single selectable option inside {@link SelectContent}.\n */\nconst SelectItem = memo(function SelectItem({\n value,\n disabled,\n children,\n style,\n testID,\n}: SelectItemProps) {\n const {\n value: selectedValue,\n setValue,\n setOpen,\n open,\n registerItem,\n unregisterItem,\n highlightedValue,\n setHighlightedValue,\n reduceMotion,\n } = useSelectContext();\n const { theme } = useUnistyles();\n const [isPressed, setIsPressed] = useState(false);\n\n const label = useMemo(() => {\n if (typeof children === 'string' || typeof children === 'number') {\n return String(children);\n }\n\n return value;\n }, [children, value]);\n\n useEffect(() => {\n registerItem(value, label);\n return () => unregisterItem(value);\n }, [label, registerItem, unregisterItem, value]);\n\n const isSelected = selectedValue === value;\n const isHighlighted = highlightedValue === value;\n const interaction = resolveSelectItemInteractionState({\n isPressed,\n isHighlighted,\n });\n\n const rootStyle = useMemo(\n () =>\n [\n getMergedSelectItemLayerStyle(theme, 'root', interaction, isSelected),\n {\n flexDirection: 'row' as const,\n alignItems: 'center' as const,\n justifyContent: 'space-between' as const,\n width: '100%' as const,\n opacity: disabled ? 0.5 : 1,\n },\n style,\n ] as StyleProp<ViewStyle>,\n [disabled, interaction, isSelected, style, theme],\n );\n\n const textStyle = useMemo(\n () => getMergedSelectItemLayerStyle(theme, 'text', interaction, isSelected),\n [interaction, isSelected, theme],\n );\n\n const endIconStyle = useMemo(\n () => getMergedSelectItemLayerStyle(theme, 'endIcon', interaction, isSelected),\n [interaction, isSelected, theme],\n );\n\n const checkScale = useDerivedValue(\n () =>\n withTiming(isSelected ? 1 : 0, {\n duration: reduceMotion ? 0 : 120,\n easing: Easing.out(Easing.ease),\n }),\n [isSelected, reduceMotion],\n );\n\n const checkAnimatedStyle = useAnimatedStyle(() => ({\n opacity: checkScale.value,\n transform: [{ scale: 0.7 + checkScale.value * 0.3 }],\n }));\n\n const handlePress = useCallback(() => {\n if (disabled) {\n return;\n }\n\n setValue(value);\n setOpen(false);\n setHighlightedValue(null);\n }, [disabled, setHighlightedValue, setOpen, setValue, value]);\n\n const handlePressIn = useCallback(() => {\n if (disabled) {\n return;\n }\n\n setIsPressed(true);\n setHighlightedValue(value);\n }, [disabled, setHighlightedValue, value]);\n\n const handlePressOut = useCallback(() => {\n setIsPressed(false);\n }, []);\n\n if (!open) {\n return null;\n }\n\n return (\n <RNPressable\n testID={testID}\n disabled={disabled}\n onPress={handlePress}\n onPressIn={handlePressIn}\n onPressOut={handlePressOut}\n style={rootStyle}\n accessibilityRole=\"menuitem\"\n accessibilityState={{ disabled: !!disabled, selected: isSelected }}\n >\n <HStack columnGap=\"2\" alignItems=\"center\" justifyContent=\"flex-start\" style={{ flex: 1 }}>\n <RNText style={textStyle} numberOfLines={1}>\n {children}\n </RNText>\n </HStack>\n\n <Animated.View style={checkAnimatedStyle} pointerEvents=\"none\">\n <IconSlot icon=\"Check\" size=\"sm\" variant=\"fill\" style={endIconStyle} />\n </Animated.View>\n </RNPressable>\n );\n});\n\nSelectItem.displayName = 'SelectItem';\n\nexport { SelectItem, type SelectItemProps };\n"],"mappings":";;;;;;;;;;;;;;;;AAoCA,MAAM,aAAa,KAAK,SAAS,WAAW,EAC1C,OACA,UACA,UACA,OACA,UACkB;CAClB,MAAM,EACJ,OAAO,eACP,UACA,SACA,MACA,cACA,gBACA,kBACA,qBACA,iBACE,kBAAkB;CACtB,MAAM,EAAE,UAAU,cAAc;CAChC,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CAEjD,MAAM,QAAQ,cAAc;EAC1B,IAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UACtD,OAAO,OAAO,SAAS;EAGzB,OAAO;IACN,CAAC,UAAU,MAAM,CAAC;CAErB,gBAAgB;EACd,aAAa,OAAO,MAAM;EAC1B,aAAa,eAAe,MAAM;IACjC;EAAC;EAAO;EAAc;EAAgB;EAAM,CAAC;CAEhD,MAAM,aAAa,kBAAkB;CAErC,MAAM,cAAc,kCAAkC;EACpD;EACA,eAHoB,qBAAqB;EAI1C,CAAC;CAEF,MAAM,YAAY,cAEd;EACE,8BAA8B,OAAO,QAAQ,aAAa,WAAW;EACrE;GACE,eAAe;GACf,YAAY;GACZ,gBAAgB;GAChB,OAAO;GACP,SAAS,WAAW,KAAM;GAC3B;EACD;EACD,EACH;EAAC;EAAU;EAAa;EAAY;EAAO;EAAM,CAClD;CAED,MAAM,YAAY,cACV,8BAA8B,OAAO,QAAQ,aAAa,WAAW,EAC3E;EAAC;EAAa;EAAY;EAAM,CACjC;CAED,MAAM,eAAe,cACb,8BAA8B,OAAO,WAAW,aAAa,WAAW,EAC9E;EAAC;EAAa;EAAY;EAAM,CACjC;CAED,MAAM,aAAa,sBAEf,WAAW,aAAa,IAAI,GAAG;EAC7B,UAAU,eAAe,IAAI;EAC7B,QAAQ,OAAO,IAAI,OAAO,KAAK;EAChC,CAAC,EACJ,CAAC,YAAY,aAAa,CAC3B;CAED,MAAM,qBAAqB,wBAAwB;EACjD,SAAS,WAAW;EACpB,WAAW,CAAC,EAAE,OAAO,KAAM,WAAW,QAAQ,IAAK,CAAC;EACrD,EAAE;CAEH,MAAM,cAAc,kBAAkB;EACpC,IAAI,UACF;EAGF,SAAS,MAAM;EACf,QAAQ,MAAM;EACd,oBAAoB,KAAK;IACxB;EAAC;EAAU;EAAqB;EAAS;EAAU;EAAM,CAAC;CAE7D,MAAM,gBAAgB,kBAAkB;EACtC,IAAI,UACF;EAGF,aAAa,KAAK;EAClB,oBAAoB,MAAM;IACzB;EAAC;EAAU;EAAqB;EAAM,CAAC;CAE1C,MAAM,iBAAiB,kBAAkB;EACvC,aAAa,MAAM;IAClB,EAAE,CAAC;CAEN,IAAI,CAAC,MACH,OAAO;CAGT,OACE,qBAACA,WAAD;EACU;EACE;EACV,SAAS;EACT,WAAW;EACX,YAAY;EACZ,OAAO;EACP,mBAAkB;EAClB,oBAAoB;GAAE,UAAU,CAAC,CAAC;GAAU,UAAU;GAAY;YARpE,CAUE,oBAAC,QAAD;GAAQ,WAAU;GAAI,YAAW;GAAS,gBAAe;GAAa,OAAO,EAAE,MAAM,GAAG;aACtF,oBAACC,MAAD;IAAQ,OAAO;IAAW,eAAe;IACtC;IACM,CAAA;GACF,CAAA,EAET,oBAAC,SAAS,MAAV;GAAe,OAAO;GAAoB,eAAc;aACtD,oBAAC,UAAD;IAAU,MAAK;IAAQ,MAAK;IAAK,SAAQ;IAAO,OAAO;IAAgB,CAAA;GACzD,CAAA,CACJ;;EAEhB;AAEF,WAAW,cAAc"}
|