@yahoo/uds-mobile 2.9.0 → 2.11.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 (206) hide show
  1. package/README.md +22 -24
  2. package/dist/components/Avatar.cjs +1 -1
  3. package/dist/components/Avatar.d.cts +1 -1
  4. package/dist/components/Avatar.d.ts +1 -1
  5. package/dist/components/Avatar.js +1 -1
  6. package/dist/components/Avatar.js.map +1 -1
  7. package/dist/components/Badge.cjs +1 -1
  8. package/dist/components/Badge.d.cts +1 -1
  9. package/dist/components/Badge.d.ts +1 -1
  10. package/dist/components/Badge.js +1 -1
  11. package/dist/components/Badge.js.map +1 -1
  12. package/dist/components/BlurTarget.cjs +2 -1
  13. package/dist/components/BlurTarget.d.cts +2 -1
  14. package/dist/components/BlurTarget.d.cts.map +1 -1
  15. package/dist/components/BlurTarget.d.ts +2 -1
  16. package/dist/components/BlurTarget.d.ts.map +1 -1
  17. package/dist/components/BlurTarget.js +2 -1
  18. package/dist/components/BlurTarget.js.map +1 -1
  19. package/dist/components/Box.cjs +1 -1
  20. package/dist/components/Box.d.cts +1 -1
  21. package/dist/components/Box.d.ts +1 -1
  22. package/dist/components/Box.js +1 -1
  23. package/dist/components/Box.js.map +1 -1
  24. package/dist/components/Button.cjs +1 -1
  25. package/dist/components/Button.d.cts +1 -1
  26. package/dist/components/Button.d.ts +1 -1
  27. package/dist/components/Button.js +1 -1
  28. package/dist/components/Button.js.map +1 -1
  29. package/dist/components/Checkbox.cjs +1 -1
  30. package/dist/components/Checkbox.d.cts +1 -1
  31. package/dist/components/Checkbox.d.ts +1 -1
  32. package/dist/components/Checkbox.js +1 -1
  33. package/dist/components/Checkbox.js.map +1 -1
  34. package/dist/components/Chip.cjs +1 -1
  35. package/dist/components/Chip.d.cts +1 -1
  36. package/dist/components/Chip.d.ts +1 -1
  37. package/dist/components/Chip.js +1 -1
  38. package/dist/components/Chip.js.map +1 -1
  39. package/dist/components/Divider/Divider.cjs +103 -0
  40. package/dist/components/Divider/Divider.d.cts +50 -0
  41. package/dist/components/Divider/Divider.d.cts.map +1 -0
  42. package/dist/components/Divider/Divider.d.ts +50 -0
  43. package/dist/components/Divider/Divider.d.ts.map +1 -0
  44. package/dist/components/Divider/Divider.js +103 -0
  45. package/dist/components/Divider/Divider.js.map +1 -0
  46. package/dist/components/Divider/DividerLabel.cjs +37 -0
  47. package/dist/components/Divider/DividerLabel.d.cts +18 -0
  48. package/dist/components/Divider/DividerLabel.d.cts.map +1 -0
  49. package/dist/components/Divider/DividerLabel.d.ts +18 -0
  50. package/dist/components/Divider/DividerLabel.d.ts.map +1 -0
  51. package/dist/components/Divider/DividerLabel.js +37 -0
  52. package/dist/components/Divider/DividerLabel.js.map +1 -0
  53. package/dist/components/Divider/DividerLine.cjs +62 -0
  54. package/dist/components/Divider/DividerLine.d.cts +19 -0
  55. package/dist/components/Divider/DividerLine.d.cts.map +1 -0
  56. package/dist/components/Divider/DividerLine.d.ts +19 -0
  57. package/dist/components/Divider/DividerLine.d.ts.map +1 -0
  58. package/dist/components/Divider/DividerLine.js +62 -0
  59. package/dist/components/Divider/DividerLine.js.map +1 -0
  60. package/dist/components/Divider/index.cjs +8 -0
  61. package/dist/components/Divider/index.d.cts +6 -0
  62. package/dist/components/Divider/index.d.ts +6 -0
  63. package/dist/components/Divider/index.js +5 -0
  64. package/dist/components/Divider/types.cjs +1 -0
  65. package/dist/components/Divider/types.d.cts +35 -0
  66. package/dist/components/Divider/types.d.cts.map +1 -0
  67. package/dist/components/Divider/types.d.ts +35 -0
  68. package/dist/components/Divider/types.d.ts.map +1 -0
  69. package/dist/components/Divider/types.js +1 -0
  70. package/dist/components/Divider/utils.cjs +33 -0
  71. package/dist/components/Divider/utils.d.cts +12 -0
  72. package/dist/components/Divider/utils.d.cts.map +1 -0
  73. package/dist/components/Divider/utils.d.ts +12 -0
  74. package/dist/components/Divider/utils.d.ts.map +1 -0
  75. package/dist/components/Divider/utils.js +31 -0
  76. package/dist/components/Divider/utils.js.map +1 -0
  77. package/dist/components/HStack.cjs +1 -1
  78. package/dist/components/HStack.d.cts +1 -1
  79. package/dist/components/HStack.d.ts +1 -1
  80. package/dist/components/HStack.js +1 -1
  81. package/dist/components/HStack.js.map +1 -1
  82. package/dist/components/Icon.cjs +1 -1
  83. package/dist/components/Icon.d.cts +2 -2
  84. package/dist/components/Icon.d.ts +2 -2
  85. package/dist/components/Icon.js +1 -1
  86. package/dist/components/Icon.js.map +1 -1
  87. package/dist/components/IconButton.cjs +1 -1
  88. package/dist/components/IconButton.d.cts +1 -1
  89. package/dist/components/IconButton.d.ts +1 -1
  90. package/dist/components/IconButton.js +1 -1
  91. package/dist/components/IconButton.js.map +1 -1
  92. package/dist/components/IconSlot.cjs +1 -1
  93. package/dist/components/IconSlot.d.cts +1 -1
  94. package/dist/components/IconSlot.d.ts +1 -1
  95. package/dist/components/IconSlot.js +1 -1
  96. package/dist/components/IconSlot.js.map +1 -1
  97. package/dist/components/Image.cjs +1 -1
  98. package/dist/components/Image.d.cts +1 -1
  99. package/dist/components/Image.d.ts +1 -1
  100. package/dist/components/Image.js +1 -1
  101. package/dist/components/Image.js.map +1 -1
  102. package/dist/components/Input.cjs +1 -1
  103. package/dist/components/Input.d.cts +1 -1
  104. package/dist/components/Input.d.ts +1 -1
  105. package/dist/components/Input.js +1 -1
  106. package/dist/components/Input.js.map +1 -1
  107. package/dist/components/Link.cjs +1 -1
  108. package/dist/components/Link.d.cts +1 -1
  109. package/dist/components/Link.d.ts +1 -1
  110. package/dist/components/Link.js +1 -1
  111. package/dist/components/Link.js.map +1 -1
  112. package/dist/components/Pressable.cjs +1 -1
  113. package/dist/components/Pressable.d.cts +1 -1
  114. package/dist/components/Pressable.d.ts +1 -1
  115. package/dist/components/Pressable.js +1 -1
  116. package/dist/components/Pressable.js.map +1 -1
  117. package/dist/components/Radio.cjs +1 -1
  118. package/dist/components/Radio.d.cts +1 -1
  119. package/dist/components/Radio.d.ts +1 -1
  120. package/dist/components/Radio.js +1 -1
  121. package/dist/components/Radio.js.map +1 -1
  122. package/dist/components/Screen.cjs +1 -1
  123. package/dist/components/Screen.d.cts +1 -1
  124. package/dist/components/Screen.d.ts +1 -1
  125. package/dist/components/Screen.js +1 -1
  126. package/dist/components/Screen.js.map +1 -1
  127. package/dist/components/Switch.cjs +1 -1
  128. package/dist/components/Switch.d.cts +1 -1
  129. package/dist/components/Switch.d.ts +1 -1
  130. package/dist/components/Switch.js +1 -1
  131. package/dist/components/Switch.js.map +1 -1
  132. package/dist/components/Tabs/Tab.cjs +174 -0
  133. package/dist/components/Tabs/Tab.d.cts +26 -0
  134. package/dist/components/Tabs/Tab.d.cts.map +1 -0
  135. package/dist/components/Tabs/Tab.d.ts +26 -0
  136. package/dist/components/Tabs/Tab.d.ts.map +1 -0
  137. package/dist/components/Tabs/Tab.js +174 -0
  138. package/dist/components/Tabs/Tab.js.map +1 -0
  139. package/dist/components/Tabs/TabList.cjs +142 -0
  140. package/dist/components/Tabs/TabList.d.cts +24 -0
  141. package/dist/components/Tabs/TabList.d.cts.map +1 -0
  142. package/dist/components/Tabs/TabList.d.ts +24 -0
  143. package/dist/components/Tabs/TabList.d.ts.map +1 -0
  144. package/dist/components/Tabs/TabList.js +141 -0
  145. package/dist/components/Tabs/TabList.js.map +1 -0
  146. package/dist/components/Tabs/TabPanel.cjs +31 -0
  147. package/dist/components/Tabs/TabPanel.d.cts +24 -0
  148. package/dist/components/Tabs/TabPanel.d.cts.map +1 -0
  149. package/dist/components/Tabs/TabPanel.d.ts +24 -0
  150. package/dist/components/Tabs/TabPanel.d.ts.map +1 -0
  151. package/dist/components/Tabs/TabPanel.js +31 -0
  152. package/dist/components/Tabs/TabPanel.js.map +1 -0
  153. package/dist/components/Tabs/Tabs.cjs +53 -0
  154. package/dist/components/Tabs/Tabs.d.cts +35 -0
  155. package/dist/components/Tabs/Tabs.d.cts.map +1 -0
  156. package/dist/components/Tabs/Tabs.d.ts +35 -0
  157. package/dist/components/Tabs/Tabs.d.ts.map +1 -0
  158. package/dist/components/Tabs/Tabs.js +53 -0
  159. package/dist/components/Tabs/Tabs.js.map +1 -0
  160. package/dist/components/Tabs/index.cjs +10 -0
  161. package/dist/components/Tabs/index.d.cts +13 -0
  162. package/dist/components/Tabs/index.d.cts.map +1 -0
  163. package/dist/components/Tabs/index.d.ts +13 -0
  164. package/dist/components/Tabs/index.d.ts.map +1 -0
  165. package/dist/components/Tabs/index.js +6 -0
  166. package/dist/components/Tabs/tabTheme.cjs +29 -0
  167. package/dist/components/Tabs/tabTheme.d.cts +23 -0
  168. package/dist/components/Tabs/tabTheme.d.cts.map +1 -0
  169. package/dist/components/Tabs/tabTheme.d.ts +23 -0
  170. package/dist/components/Tabs/tabTheme.d.ts.map +1 -0
  171. package/dist/components/Tabs/tabTheme.js +28 -0
  172. package/dist/components/Tabs/tabTheme.js.map +1 -0
  173. package/dist/components/Tabs/tabsContexts.cjs +91 -0
  174. package/dist/components/Tabs/tabsContexts.d.cts +35 -0
  175. package/dist/components/Tabs/tabsContexts.d.cts.map +1 -0
  176. package/dist/components/Tabs/tabsContexts.d.ts +35 -0
  177. package/dist/components/Tabs/tabsContexts.d.ts.map +1 -0
  178. package/dist/components/Tabs/tabsContexts.js +87 -0
  179. package/dist/components/Tabs/tabsContexts.js.map +1 -0
  180. package/dist/components/Text.cjs +1 -1
  181. package/dist/components/Text.d.cts +1 -1
  182. package/dist/components/Text.d.ts +1 -1
  183. package/dist/components/Text.js +1 -1
  184. package/dist/components/Text.js.map +1 -1
  185. package/dist/components/VStack.cjs +1 -1
  186. package/dist/components/VStack.d.cts +1 -1
  187. package/dist/components/VStack.d.ts +1 -1
  188. package/dist/components/VStack.js +1 -1
  189. package/dist/components/VStack.js.map +1 -1
  190. package/dist/jest/mocks/styles.cjs +22 -0
  191. package/dist/jest/mocks/styles.d.cts +4 -2
  192. package/dist/jest/mocks/styles.d.cts.map +1 -1
  193. package/dist/jest/mocks/styles.d.ts +4 -2
  194. package/dist/jest/mocks/styles.d.ts.map +1 -1
  195. package/dist/jest/mocks/styles.js +21 -1
  196. package/dist/jest/mocks/styles.js.map +1 -1
  197. package/dist/types/dist/index.d.cts +63 -2
  198. package/dist/types/dist/index.d.cts.map +1 -1
  199. package/dist/types/dist/index.d.ts +63 -2
  200. package/dist/types/dist/index.d.ts.map +1 -1
  201. package/fonts/uds-icons.ttf +0 -0
  202. package/generated/styles.cjs +87 -13
  203. package/generated/styles.d.ts +58 -0
  204. package/generated/styles.mjs +87 -13
  205. package/generated/unistyles.d.ts +62 -9
  206. package/package.json +21 -1
@@ -0,0 +1,174 @@
1
+ /*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
2
+ import { IconSlot } from "../IconSlot.js";
3
+ import { Pressable as Pressable$1 } from "../Pressable.js";
4
+ import { useTabSelectionContext, useTabsVisualContext } from "./tabsContexts.js";
5
+ import { getMergedTabLayerStyle, getTabLayerStyle } from "./tabTheme.js";
6
+ import { memo, useCallback, useEffect, useId, useMemo, useState } from "react";
7
+ import { Text, View } from "react-native";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { useUnistyles } from "react-native-unistyles";
10
+ //#region src/components/Tabs/Tab.tsx
11
+ const PRIMARY_TAB_UNDERLINE_HEIGHT = 2;
12
+ const CLEAR_SELECTION_CHROME = {
13
+ backgroundColor: "transparent",
14
+ borderWidth: 0,
15
+ borderColor: "transparent",
16
+ shadowOpacity: 0,
17
+ elevation: 0,
18
+ boxShadow: []
19
+ };
20
+ function TabLabel({ style, children }) {
21
+ if (typeof children === "string" || typeof children === "number") return /* @__PURE__ */ jsx(Text, {
22
+ style,
23
+ children
24
+ });
25
+ return children;
26
+ }
27
+ /**
28
+ * **⚙️ Tab**
29
+ *
30
+ * @description
31
+ * A single selectable tab. Must be used inside {@link TabList} within {@link Tabs}.
32
+ *
33
+ * @category Navigation
34
+ * @platform mobile
35
+ */
36
+ const Tab = memo(function Tab({ value, children, startIcon, endIcon, disabled, style, ...pressableRest }) {
37
+ const generatedId = useId();
38
+ const uid = value ?? `uds-tab-${generatedId}`;
39
+ const { variant: visualVariant, reduceMotion } = useTabsVisualContext();
40
+ const { selectedId, setSelectedId, registerTab, unregisterTab, setTabLayout } = useTabSelectionContext();
41
+ const { theme } = useUnistyles();
42
+ const [pressed, setPressed] = useState(false);
43
+ const selected = !disabled && selectedId === uid;
44
+ const active = selected ? "on" : "off";
45
+ const interaction = pressed ? "pressed" : "rest";
46
+ useEffect(() => {
47
+ registerTab(uid);
48
+ return () => {
49
+ unregisterTab(uid);
50
+ };
51
+ }, [
52
+ uid,
53
+ registerTab,
54
+ unregisterTab
55
+ ]);
56
+ const rootBase = useMemo(() => getMergedTabLayerStyle(theme, visualVariant, active, "root", interaction), [
57
+ theme,
58
+ visualVariant,
59
+ active,
60
+ interaction
61
+ ]);
62
+ const textStyle = useMemo(() => getMergedTabLayerStyle(theme, visualVariant, active, "rootText", interaction), [
63
+ theme,
64
+ visualVariant,
65
+ active,
66
+ interaction
67
+ ]);
68
+ const iconStyle = useMemo(() => getMergedTabLayerStyle(theme, visualVariant, active, "icon", interaction), [
69
+ theme,
70
+ visualVariant,
71
+ active,
72
+ interaction
73
+ ]);
74
+ const iconColor = (() => {
75
+ const c = iconStyle?.color;
76
+ if (c === void 0 || c === null) return;
77
+ return c;
78
+ })();
79
+ /** Inactive primary tabs use transparent underline tokens on web; RN has no CSS vars for that layer. */
80
+ const showPrimaryPerTabUnderline = visualVariant === "primary" && !(selected && !reduceMotion);
81
+ const primaryUnderlineColor = useMemo(() => {
82
+ if (visualVariant !== "primary") return;
83
+ if (selected && reduceMotion) {
84
+ const c = getTabLayerStyle(theme, "primary", "on", "rootText", "rest").color;
85
+ if (typeof c === "string") return c;
86
+ }
87
+ return "transparent";
88
+ }, [
89
+ visualVariant,
90
+ selected,
91
+ reduceMotion,
92
+ theme
93
+ ]);
94
+ const rootStyle = useMemo(() => {
95
+ const base = {
96
+ ...rootBase,
97
+ flexDirection: "row",
98
+ alignItems: "center",
99
+ flexShrink: 0,
100
+ zIndex: 1,
101
+ position: "relative"
102
+ };
103
+ if (selected && !reduceMotion) return {
104
+ ...base,
105
+ ...CLEAR_SELECTION_CHROME
106
+ };
107
+ return base;
108
+ }, [
109
+ rootBase,
110
+ selected,
111
+ reduceMotion
112
+ ]);
113
+ const onLayout = useCallback((e) => {
114
+ setTabLayout(uid, e.nativeEvent.layout);
115
+ }, [uid, setTabLayout]);
116
+ const onPress = useCallback(() => {
117
+ if (disabled) return;
118
+ setSelectedId(uid);
119
+ }, [
120
+ disabled,
121
+ setSelectedId,
122
+ uid
123
+ ]);
124
+ return /* @__PURE__ */ jsxs(Pressable$1, {
125
+ accessibilityRole: "tab",
126
+ accessibilityState: {
127
+ selected,
128
+ disabled: !!disabled
129
+ },
130
+ disabled,
131
+ onPress,
132
+ onPressIn: () => setPressed(true),
133
+ onPressOut: () => setPressed(false),
134
+ onLayout,
135
+ style: [rootStyle, style],
136
+ ...pressableRest,
137
+ children: [
138
+ startIcon ? /* @__PURE__ */ jsx(IconSlot, {
139
+ icon: startIcon,
140
+ size: "sm",
141
+ style: iconStyle,
142
+ ...iconColor !== void 0 ? { color: iconColor } : {}
143
+ }) : null,
144
+ /* @__PURE__ */ jsx(TabLabel, {
145
+ style: textStyle,
146
+ children
147
+ }),
148
+ endIcon ? /* @__PURE__ */ jsx(IconSlot, {
149
+ icon: endIcon,
150
+ size: "sm",
151
+ style: iconStyle,
152
+ ...iconColor !== void 0 ? { color: iconColor } : {}
153
+ }) : null,
154
+ showPrimaryPerTabUnderline && primaryUnderlineColor && primaryUnderlineColor !== "transparent" ? /* @__PURE__ */ jsx(View, {
155
+ accessibilityElementsHidden: true,
156
+ importantForAccessibility: "no-hide-descendants",
157
+ pointerEvents: "none",
158
+ style: {
159
+ position: "absolute",
160
+ left: 0,
161
+ right: 0,
162
+ bottom: 0,
163
+ height: PRIMARY_TAB_UNDERLINE_HEIGHT,
164
+ backgroundColor: primaryUnderlineColor
165
+ }
166
+ }) : null
167
+ ]
168
+ });
169
+ });
170
+ Tab.displayName = "Tab";
171
+ //#endregion
172
+ export { Tab };
173
+
174
+ //# sourceMappingURL=Tab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tab.js","names":["RNText","Pressable"],"sources":["../../../src/components/Tabs/Tab.tsx"],"sourcesContent":["import type { UniversalTabProps } from '@yahoo/uds-types';\nimport type { ReactElement, ReactNode } from 'react';\nimport { memo, useCallback, useEffect, useId, useMemo, useState } from 'react';\nimport type { LayoutChangeEvent, PressableProps, TextStyle, ViewStyle } from 'react-native';\nimport { Text as RNText, View } from 'react-native';\n// eslint-disable-next-line uds/no-use-unistyles -- theme.components path lookups for tab layers\nimport { useUnistyles } from 'react-native-unistyles';\n\nimport type { StyleProps } from '../../../generated/styles';\nimport type { IconSlotType } from '../IconSlot';\nimport { IconSlot } from '../IconSlot';\nimport { Pressable } from '../Pressable';\nimport { useTabSelectionContext, useTabsVisualContext } from './tabsContexts';\nimport { getMergedTabLayerStyle, getTabLayerStyle } from './tabTheme';\n\nconst PRIMARY_TAB_UNDERLINE_HEIGHT = 2;\n\ninterface TabProps\n extends\n Omit<PressableProps, 'children' | 'style' | 'disabled' | 'onPress'>,\n Omit<UniversalTabProps, 'asChild' | 'className' | 'startIcon' | 'endIcon'> {\n children: UniversalTabProps['children'];\n startIcon?: IconSlotType;\n endIcon?: IconSlotType;\n style?: ViewStyle;\n}\n\nconst CLEAR_SELECTION_CHROME: ViewStyle = {\n backgroundColor: 'transparent',\n borderWidth: 0,\n borderColor: 'transparent',\n shadowOpacity: 0,\n elevation: 0,\n boxShadow: [],\n};\n\nfunction TabLabel({ style, children }: { style: TextStyle; children: ReactNode }) {\n if (typeof children === 'string' || typeof children === 'number') {\n return <RNText style={style}>{children}</RNText>;\n }\n return children as ReactElement;\n}\n\n/**\n * **⚙️ Tab**\n *\n * @description\n * A single selectable tab. Must be used inside {@link TabList} within {@link Tabs}.\n *\n * @category Navigation\n * @platform mobile\n */\nconst Tab = memo(function Tab({\n value,\n children,\n startIcon,\n endIcon,\n disabled,\n style,\n ...pressableRest\n}: TabProps) {\n const generatedId = useId();\n const uid = value ?? `uds-tab-${generatedId}`;\n const { variant: visualVariant, reduceMotion } = useTabsVisualContext();\n const { selectedId, setSelectedId, registerTab, unregisterTab, setTabLayout } =\n useTabSelectionContext();\n const { theme } = useUnistyles();\n const [pressed, setPressed] = useState(false);\n\n const selected = !disabled && selectedId === uid;\n const active: 'on' | 'off' = selected ? 'on' : 'off';\n const interaction: 'rest' | 'pressed' = pressed ? 'pressed' : 'rest';\n\n useEffect(() => {\n registerTab(uid);\n return () => {\n unregisterTab(uid);\n };\n }, [uid, registerTab, unregisterTab]);\n\n const rootBase = useMemo(\n () => getMergedTabLayerStyle(theme, visualVariant, active, 'root', interaction) as ViewStyle,\n [theme, visualVariant, active, interaction],\n );\n const textStyle = useMemo(\n () =>\n getMergedTabLayerStyle(theme, visualVariant, active, 'rootText', interaction) as TextStyle,\n [theme, visualVariant, active, interaction],\n );\n const iconStyle = useMemo(\n () => getMergedTabLayerStyle(theme, visualVariant, active, 'icon', interaction) as TextStyle,\n [theme, visualVariant, active, interaction],\n );\n\n const iconColor = ((): StyleProps['color'] | undefined => {\n const c = iconStyle?.color;\n if (c === undefined || c === null) {\n return undefined;\n }\n return c as StyleProps['color'];\n })();\n\n /** Inactive primary tabs use transparent underline tokens on web; RN has no CSS vars for that layer. */\n const showPrimaryPerTabUnderline = visualVariant === 'primary' && !(selected && !reduceMotion);\n\n const primaryUnderlineColor = useMemo(() => {\n if (visualVariant !== 'primary') {\n return undefined;\n }\n if (selected && reduceMotion) {\n const onText = getTabLayerStyle(theme, 'primary', 'on', 'rootText', 'rest') as TextStyle;\n const c = onText.color;\n if (typeof c === 'string') {\n return c;\n }\n }\n return 'transparent';\n }, [visualVariant, selected, reduceMotion, theme]);\n\n const rootStyle = useMemo((): ViewStyle => {\n const base: ViewStyle = {\n ...rootBase,\n flexDirection: 'row',\n alignItems: 'center',\n flexShrink: 0,\n zIndex: 1,\n position: 'relative',\n };\n if (selected && !reduceMotion) {\n return { ...base, ...CLEAR_SELECTION_CHROME };\n }\n return base;\n }, [rootBase, selected, reduceMotion]);\n\n const onLayout = useCallback(\n (e: LayoutChangeEvent) => {\n setTabLayout(uid, e.nativeEvent.layout);\n },\n [uid, setTabLayout],\n );\n\n const onPress = useCallback(() => {\n if (disabled) {\n return;\n }\n setSelectedId(uid);\n }, [disabled, setSelectedId, uid]);\n\n return (\n <Pressable\n accessibilityRole=\"tab\"\n accessibilityState={{ selected, disabled: !!disabled }}\n disabled={disabled}\n onPress={onPress}\n onPressIn={() => setPressed(true)}\n onPressOut={() => setPressed(false)}\n onLayout={onLayout}\n style={[rootStyle, style]}\n {...pressableRest}\n >\n {startIcon ? (\n <IconSlot\n icon={startIcon}\n size=\"sm\"\n style={iconStyle}\n {...(iconColor !== undefined ? { color: iconColor } : {})}\n />\n ) : null}\n <TabLabel style={textStyle}>{children}</TabLabel>\n {endIcon ? (\n <IconSlot\n icon={endIcon}\n size=\"sm\"\n style={iconStyle}\n {...(iconColor !== undefined ? { color: iconColor } : {})}\n />\n ) : null}\n {showPrimaryPerTabUnderline &&\n primaryUnderlineColor &&\n primaryUnderlineColor !== 'transparent' ? (\n <View\n accessibilityElementsHidden\n importantForAccessibility=\"no-hide-descendants\"\n pointerEvents=\"none\"\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: 0,\n height: PRIMARY_TAB_UNDERLINE_HEIGHT,\n backgroundColor: primaryUnderlineColor,\n }}\n />\n ) : null}\n </Pressable>\n );\n});\n\nTab.displayName = 'Tab';\n\nexport { Tab };\nexport type { TabProps };\n"],"mappings":"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"}
@@ -0,0 +1,142 @@
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_Tabs_tabsContexts = require("./tabsContexts.cjs");
5
+ const require_components_Tabs_tabTheme = require("./tabTheme.cjs");
6
+ let react = require("react");
7
+ let react_native = require("react-native");
8
+ let react_jsx_runtime = require("react/jsx-runtime");
9
+ let generated_styles = require("../../../generated/styles");
10
+ let react_native_unistyles = require("react-native-unistyles");
11
+ let react_native_reanimated = require("react-native-reanimated");
12
+ react_native_reanimated = require_runtime.__toESM(react_native_reanimated);
13
+ //#region src/components/Tabs/TabList.tsx
14
+ const TAB_INDICATOR_MS = 240;
15
+ const TAB_INDICATOR_EASING = react_native_reanimated.Easing.bezier(.2, 0, 0, 1);
16
+ const PRIMARY_SLIDE_UNDERLINE_HEIGHT = 2;
17
+ function TabListIndicator({ visualVariant, reduceMotion }) {
18
+ const { selectedId, tabLayouts } = require_components_Tabs_tabsContexts.useTabSelectionContext();
19
+ const { theme } = (0, react_native_unistyles.useUnistyles)();
20
+ const x = (0, react_native_reanimated.useSharedValue)(0);
21
+ const y = (0, react_native_reanimated.useSharedValue)(0);
22
+ const w = (0, react_native_reanimated.useSharedValue)(0);
23
+ const h = (0, react_native_reanimated.useSharedValue)(0);
24
+ const opacity = (0, react_native_reanimated.useSharedValue)(0);
25
+ (0, react.useEffect)(() => {
26
+ if (reduceMotion || !selectedId) {
27
+ opacity.value = (0, react_native_reanimated.withTiming)(0, {
28
+ duration: 120,
29
+ easing: react_native_reanimated.Easing.out(react_native_reanimated.Easing.quad)
30
+ });
31
+ return;
32
+ }
33
+ const layout = tabLayouts.get(selectedId);
34
+ if (!layout || layout.width <= 0 || layout.height <= 0) {
35
+ opacity.value = (0, react_native_reanimated.withTiming)(0, {
36
+ duration: 120,
37
+ easing: react_native_reanimated.Easing.out(react_native_reanimated.Easing.quad)
38
+ });
39
+ return;
40
+ }
41
+ const timing = {
42
+ duration: TAB_INDICATOR_MS,
43
+ easing: TAB_INDICATOR_EASING
44
+ };
45
+ x.value = (0, react_native_reanimated.withTiming)(layout.x, timing);
46
+ y.value = (0, react_native_reanimated.withTiming)(layout.y, timing);
47
+ w.value = (0, react_native_reanimated.withTiming)(layout.width, timing);
48
+ h.value = (0, react_native_reanimated.withTiming)(layout.height, timing);
49
+ opacity.value = (0, react_native_reanimated.withTiming)(1, timing);
50
+ }, [
51
+ selectedId,
52
+ tabLayouts,
53
+ reduceMotion,
54
+ x,
55
+ y,
56
+ w,
57
+ h,
58
+ opacity
59
+ ]);
60
+ const indicatorChrome = (0, react.useMemo)(() => require_components_Tabs_tabTheme.getTabLayerStyle(theme, visualVariant, "on", "root", "rest"), [theme, visualVariant]);
61
+ const primaryAccentColor = (0, react.useMemo)(() => {
62
+ const t = require_components_Tabs_tabTheme.getTabLayerStyle(theme, "primary", "on", "rootText", "rest");
63
+ return typeof t.color === "string" ? t.color : "#7d2eff";
64
+ }, [theme]);
65
+ const animatedStyle = (0, react_native_reanimated.useAnimatedStyle)(() => ({
66
+ position: "absolute",
67
+ left: x.value,
68
+ top: y.value,
69
+ width: w.value,
70
+ height: h.value,
71
+ opacity: opacity.value,
72
+ zIndex: 0,
73
+ overflow: "hidden"
74
+ }));
75
+ if (reduceMotion) return null;
76
+ /** Primary: sliding accent line at bottom (web uses underline layer, not full pill). */
77
+ if (visualVariant === "primary") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_reanimated.default.View, {
78
+ pointerEvents: "none",
79
+ style: [animatedStyle, { backgroundColor: "transparent" }],
80
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
81
+ style: {
82
+ flex: 1,
83
+ justifyContent: "flex-end"
84
+ },
85
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: {
86
+ height: PRIMARY_SLIDE_UNDERLINE_HEIGHT,
87
+ width: "100%",
88
+ backgroundColor: primaryAccentColor
89
+ } })
90
+ })
91
+ });
92
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_reanimated.default.View, {
93
+ pointerEvents: "none",
94
+ style: animatedStyle,
95
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, { style: [indicatorChrome, { flex: 1 }] })
96
+ });
97
+ }
98
+ /**
99
+ * **⚙️ TabList**
100
+ *
101
+ * @description
102
+ * Horizontal row of {@link Tab} items. Set `scrollable` when tabs may overflow the viewport.
103
+ *
104
+ * @category Navigation
105
+ * @platform mobile
106
+ */
107
+ const TabList = (0, react.memo)(function TabList({ children, scrollable = false, style, accessibilityLabel, ...viewProps }) {
108
+ const { variant: visualVariant, reduceMotion } = require_components_Tabs_tabsContexts.useTabsVisualContext();
109
+ generated_styles.tabsStyles.useVariants({ variant: visualVariant });
110
+ const row = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_native.View, {
111
+ style: {
112
+ flexDirection: "row",
113
+ alignItems: "center",
114
+ position: "relative",
115
+ ...generated_styles.tabsStyles.root,
116
+ ...visualVariant === "secondary" && !scrollable ? { alignSelf: "flex-start" } : {}
117
+ },
118
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TabListIndicator, {
119
+ visualVariant,
120
+ reduceMotion
121
+ }), children]
122
+ });
123
+ if (scrollable) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
124
+ horizontal: true,
125
+ showsHorizontalScrollIndicator: false,
126
+ accessibilityRole: "tablist",
127
+ accessibilityLabel,
128
+ ...viewProps,
129
+ style,
130
+ children: row
131
+ });
132
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
133
+ accessibilityRole: "tablist",
134
+ accessibilityLabel,
135
+ style,
136
+ ...viewProps,
137
+ children: row
138
+ });
139
+ });
140
+ TabList.displayName = "TabList";
141
+ //#endregion
142
+ exports.TabList = TabList;
@@ -0,0 +1,24 @@
1
+
2
+ import { UniversalTabListProps } from "../../types/dist/index.cjs";
3
+ import * as _$react from "react";
4
+ import { ViewProps, ViewStyle } from "react-native";
5
+
6
+ //#region src/components/Tabs/TabList.d.ts
7
+ /** RN View/ScrollView aria types differ from `React.AriaAttributes` on web; keep parity fields only. */
8
+ interface TabListProps extends Omit<ViewProps, 'children' | 'style'>, Pick<UniversalTabListProps, 'scrollable'> {
9
+ children: UniversalTabListProps['children'];
10
+ style?: ViewStyle;
11
+ }
12
+ /**
13
+ * **⚙️ TabList**
14
+ *
15
+ * @description
16
+ * Horizontal row of {@link Tab} items. Set `scrollable` when tabs may overflow the viewport.
17
+ *
18
+ * @category Navigation
19
+ * @platform mobile
20
+ */
21
+ declare const TabList: _$react.NamedExoticComponent<TabListProps>;
22
+ //#endregion
23
+ export { TabList, type TabListProps };
24
+ //# sourceMappingURL=TabList.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabList.d.cts","names":[],"sources":["../../../src/components/Tabs/TabList.tsx"],"mappings":";;;;;;;UAsBU,YAAA,SACA,IAAA,CAAK,SAAA,yBAAkC,IAAA,CAAK,qBAAA;EACpD,QAAA,EAAU,qBAAA;EACV,KAAA,GAAQ,SAAA;AAAA;;;;;;;;;;cAiGJ,OAAA,EAAO,OAAA,CAAA,oBAAA,CAAA,YAAA"}
@@ -0,0 +1,24 @@
1
+
2
+ import { UniversalTabListProps } from "../../types/dist/index.js";
3
+ import * as _$react from "react";
4
+ import { ViewProps, ViewStyle } from "react-native";
5
+
6
+ //#region src/components/Tabs/TabList.d.ts
7
+ /** RN View/ScrollView aria types differ from `React.AriaAttributes` on web; keep parity fields only. */
8
+ interface TabListProps extends Omit<ViewProps, 'children' | 'style'>, Pick<UniversalTabListProps, 'scrollable'> {
9
+ children: UniversalTabListProps['children'];
10
+ style?: ViewStyle;
11
+ }
12
+ /**
13
+ * **⚙️ TabList**
14
+ *
15
+ * @description
16
+ * Horizontal row of {@link Tab} items. Set `scrollable` when tabs may overflow the viewport.
17
+ *
18
+ * @category Navigation
19
+ * @platform mobile
20
+ */
21
+ declare const TabList: _$react.NamedExoticComponent<TabListProps>;
22
+ //#endregion
23
+ export { TabList, type TabListProps };
24
+ //# sourceMappingURL=TabList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabList.d.ts","names":[],"sources":["../../../src/components/Tabs/TabList.tsx"],"mappings":";;;;;;;UAsBU,YAAA,SACA,IAAA,CAAK,SAAA,yBAAkC,IAAA,CAAK,qBAAA;EACpD,QAAA,EAAU,qBAAA;EACV,KAAA,GAAQ,SAAA;AAAA;;;;;;;;;;cAiGJ,OAAA,EAAO,OAAA,CAAA,oBAAA,CAAA,YAAA"}
@@ -0,0 +1,141 @@
1
+ /*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
2
+ import { useTabSelectionContext, useTabsVisualContext } from "./tabsContexts.js";
3
+ import { getTabLayerStyle } from "./tabTheme.js";
4
+ import { memo, useEffect, useMemo } from "react";
5
+ import { ScrollView, View } from "react-native";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { tabsStyles } from "../../../generated/styles";
8
+ import { useUnistyles } from "react-native-unistyles";
9
+ import Animated, { Easing, useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated";
10
+ //#region src/components/Tabs/TabList.tsx
11
+ const TAB_INDICATOR_MS = 240;
12
+ const TAB_INDICATOR_EASING = Easing.bezier(.2, 0, 0, 1);
13
+ const PRIMARY_SLIDE_UNDERLINE_HEIGHT = 2;
14
+ function TabListIndicator({ visualVariant, reduceMotion }) {
15
+ const { selectedId, tabLayouts } = useTabSelectionContext();
16
+ const { theme } = useUnistyles();
17
+ const x = useSharedValue(0);
18
+ const y = useSharedValue(0);
19
+ const w = useSharedValue(0);
20
+ const h = useSharedValue(0);
21
+ const opacity = useSharedValue(0);
22
+ useEffect(() => {
23
+ if (reduceMotion || !selectedId) {
24
+ opacity.value = withTiming(0, {
25
+ duration: 120,
26
+ easing: Easing.out(Easing.quad)
27
+ });
28
+ return;
29
+ }
30
+ const layout = tabLayouts.get(selectedId);
31
+ if (!layout || layout.width <= 0 || layout.height <= 0) {
32
+ opacity.value = withTiming(0, {
33
+ duration: 120,
34
+ easing: Easing.out(Easing.quad)
35
+ });
36
+ return;
37
+ }
38
+ const timing = {
39
+ duration: TAB_INDICATOR_MS,
40
+ easing: TAB_INDICATOR_EASING
41
+ };
42
+ x.value = withTiming(layout.x, timing);
43
+ y.value = withTiming(layout.y, timing);
44
+ w.value = withTiming(layout.width, timing);
45
+ h.value = withTiming(layout.height, timing);
46
+ opacity.value = withTiming(1, timing);
47
+ }, [
48
+ selectedId,
49
+ tabLayouts,
50
+ reduceMotion,
51
+ x,
52
+ y,
53
+ w,
54
+ h,
55
+ opacity
56
+ ]);
57
+ const indicatorChrome = useMemo(() => getTabLayerStyle(theme, visualVariant, "on", "root", "rest"), [theme, visualVariant]);
58
+ const primaryAccentColor = useMemo(() => {
59
+ const t = getTabLayerStyle(theme, "primary", "on", "rootText", "rest");
60
+ return typeof t.color === "string" ? t.color : "#7d2eff";
61
+ }, [theme]);
62
+ const animatedStyle = useAnimatedStyle(() => ({
63
+ position: "absolute",
64
+ left: x.value,
65
+ top: y.value,
66
+ width: w.value,
67
+ height: h.value,
68
+ opacity: opacity.value,
69
+ zIndex: 0,
70
+ overflow: "hidden"
71
+ }));
72
+ if (reduceMotion) return null;
73
+ /** Primary: sliding accent line at bottom (web uses underline layer, not full pill). */
74
+ if (visualVariant === "primary") return /* @__PURE__ */ jsx(Animated.View, {
75
+ pointerEvents: "none",
76
+ style: [animatedStyle, { backgroundColor: "transparent" }],
77
+ children: /* @__PURE__ */ jsx(View, {
78
+ style: {
79
+ flex: 1,
80
+ justifyContent: "flex-end"
81
+ },
82
+ children: /* @__PURE__ */ jsx(View, { style: {
83
+ height: PRIMARY_SLIDE_UNDERLINE_HEIGHT,
84
+ width: "100%",
85
+ backgroundColor: primaryAccentColor
86
+ } })
87
+ })
88
+ });
89
+ return /* @__PURE__ */ jsx(Animated.View, {
90
+ pointerEvents: "none",
91
+ style: animatedStyle,
92
+ children: /* @__PURE__ */ jsx(View, { style: [indicatorChrome, { flex: 1 }] })
93
+ });
94
+ }
95
+ /**
96
+ * **⚙️ TabList**
97
+ *
98
+ * @description
99
+ * Horizontal row of {@link Tab} items. Set `scrollable` when tabs may overflow the viewport.
100
+ *
101
+ * @category Navigation
102
+ * @platform mobile
103
+ */
104
+ const TabList = memo(function TabList({ children, scrollable = false, style, accessibilityLabel, ...viewProps }) {
105
+ const { variant: visualVariant, reduceMotion } = useTabsVisualContext();
106
+ tabsStyles.useVariants({ variant: visualVariant });
107
+ const row = /* @__PURE__ */ jsxs(View, {
108
+ style: {
109
+ flexDirection: "row",
110
+ alignItems: "center",
111
+ position: "relative",
112
+ ...tabsStyles.root,
113
+ ...visualVariant === "secondary" && !scrollable ? { alignSelf: "flex-start" } : {}
114
+ },
115
+ children: [/* @__PURE__ */ jsx(TabListIndicator, {
116
+ visualVariant,
117
+ reduceMotion
118
+ }), children]
119
+ });
120
+ if (scrollable) return /* @__PURE__ */ jsx(ScrollView, {
121
+ horizontal: true,
122
+ showsHorizontalScrollIndicator: false,
123
+ accessibilityRole: "tablist",
124
+ accessibilityLabel,
125
+ ...viewProps,
126
+ style,
127
+ children: row
128
+ });
129
+ return /* @__PURE__ */ jsx(View, {
130
+ accessibilityRole: "tablist",
131
+ accessibilityLabel,
132
+ style,
133
+ ...viewProps,
134
+ children: row
135
+ });
136
+ });
137
+ TabList.displayName = "TabList";
138
+ //#endregion
139
+ export { TabList };
140
+
141
+ //# sourceMappingURL=TabList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabList.js","names":[],"sources":["../../../src/components/Tabs/TabList.tsx"],"sourcesContent":["import type { UniversalTabListProps } from '@yahoo/uds-types';\nimport { memo, useEffect, useMemo } from 'react';\nimport type { ViewProps, ViewStyle } from 'react-native';\nimport { ScrollView, View } from 'react-native';\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\n// eslint-disable-next-line uds/no-use-unistyles -- theme.components path lookups for tab indicator\nimport { useUnistyles } from 'react-native-unistyles';\n\nimport { tabsStyles } from '../../../generated/styles';\nimport { useTabSelectionContext, useTabsVisualContext } from './tabsContexts';\nimport { getTabLayerStyle } from './tabTheme';\n\nconst TAB_INDICATOR_MS = 240;\nconst TAB_INDICATOR_EASING = Easing.bezier(0.2, 0, 0, 1);\nconst PRIMARY_SLIDE_UNDERLINE_HEIGHT = 2;\n\n/** RN View/ScrollView aria types differ from `React.AriaAttributes` on web; keep parity fields only. */\ninterface TabListProps\n extends Omit<ViewProps, 'children' | 'style'>, Pick<UniversalTabListProps, 'scrollable'> {\n children: UniversalTabListProps['children'];\n style?: ViewStyle;\n}\n\nfunction TabListIndicator({\n visualVariant,\n reduceMotion,\n}: {\n visualVariant: 'primary' | 'secondary';\n reduceMotion: boolean;\n}) {\n const { selectedId, tabLayouts } = useTabSelectionContext();\n const { theme } = useUnistyles();\n const x = useSharedValue(0);\n const y = useSharedValue(0);\n const w = useSharedValue(0);\n const h = useSharedValue(0);\n const opacity = useSharedValue(0);\n\n useEffect(() => {\n if (reduceMotion || !selectedId) {\n opacity.value = withTiming(0, { duration: 120, easing: Easing.out(Easing.quad) });\n return;\n }\n const layout = tabLayouts.get(selectedId);\n if (!layout || layout.width <= 0 || layout.height <= 0) {\n opacity.value = withTiming(0, { duration: 120, easing: Easing.out(Easing.quad) });\n return;\n }\n const timing = { duration: TAB_INDICATOR_MS, easing: TAB_INDICATOR_EASING };\n x.value = withTiming(layout.x, timing);\n y.value = withTiming(layout.y, timing);\n w.value = withTiming(layout.width, timing);\n h.value = withTiming(layout.height, timing);\n opacity.value = withTiming(1, timing);\n }, [selectedId, tabLayouts, reduceMotion, x, y, w, h, opacity]);\n\n const indicatorChrome = useMemo(\n () => getTabLayerStyle(theme, visualVariant, 'on', 'root', 'rest') as ViewStyle,\n [theme, visualVariant],\n );\n\n const primaryAccentColor = useMemo(() => {\n const t = getTabLayerStyle(theme, 'primary', 'on', 'rootText', 'rest') as { color?: string };\n return typeof t.color === 'string' ? t.color : '#7d2eff';\n }, [theme]);\n\n const animatedStyle = useAnimatedStyle(() => ({\n position: 'absolute' as const,\n left: x.value,\n top: y.value,\n width: w.value,\n height: h.value,\n opacity: opacity.value,\n zIndex: 0,\n overflow: 'hidden' as const,\n }));\n\n if (reduceMotion) {\n return null;\n }\n\n /** Primary: sliding accent line at bottom (web uses underline layer, not full pill). */\n if (visualVariant === 'primary') {\n return (\n <Animated.View\n pointerEvents=\"none\"\n style={[animatedStyle, { backgroundColor: 'transparent' }]}\n >\n <View style={{ flex: 1, justifyContent: 'flex-end' }}>\n <View\n style={{\n height: PRIMARY_SLIDE_UNDERLINE_HEIGHT,\n width: '100%',\n backgroundColor: primaryAccentColor,\n }}\n />\n </View>\n </Animated.View>\n );\n }\n\n return (\n <Animated.View pointerEvents=\"none\" style={animatedStyle}>\n <View style={[indicatorChrome, { flex: 1 }]} />\n </Animated.View>\n );\n}\n\n/**\n * **⚙️ TabList**\n *\n * @description\n * Horizontal row of {@link Tab} items. Set `scrollable` when tabs may overflow the viewport.\n *\n * @category Navigation\n * @platform mobile\n */\nconst TabList = memo(function TabList({\n children,\n scrollable = false,\n style,\n accessibilityLabel,\n ...viewProps\n}: TabListProps) {\n const { variant: visualVariant, reduceMotion } = useTabsVisualContext();\n tabsStyles.useVariants({ variant: visualVariant });\n\n const rowStyle: ViewStyle = {\n flexDirection: 'row',\n alignItems: 'center',\n position: 'relative',\n ...tabsStyles.root,\n // Secondary track tokens include horizontal padding; shrink-wrap so inset matches on both ends.\n ...(visualVariant === 'secondary' && !scrollable ? { alignSelf: 'flex-start' as const } : {}),\n };\n\n const row = (\n <View style={rowStyle}>\n <TabListIndicator visualVariant={visualVariant} reduceMotion={reduceMotion} />\n {children}\n </View>\n );\n\n if (scrollable) {\n return (\n <ScrollView\n horizontal\n showsHorizontalScrollIndicator={false}\n accessibilityRole=\"tablist\"\n accessibilityLabel={accessibilityLabel}\n {...viewProps}\n style={style}\n >\n {row}\n </ScrollView>\n );\n }\n\n return (\n <View\n accessibilityRole=\"tablist\"\n accessibilityLabel={accessibilityLabel}\n style={style}\n {...viewProps}\n >\n {row}\n </View>\n );\n});\n\nTabList.displayName = 'TabList';\n\nexport { TabList };\nexport type { TabListProps };\n"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("../../_virtual/_rolldown/runtime.cjs");
4
+ const require_components_Tabs_tabsContexts = require("./tabsContexts.cjs");
5
+ let react = require("react");
6
+ let react_native = require("react-native");
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+ //#region src/components/Tabs/TabPanel.tsx
9
+ /**
10
+ * **⚙️ TabPanel**
11
+ *
12
+ * @description
13
+ * Content associated with a tab id. Only the panel whose `tabId` matches the current
14
+ * selection is rendered.
15
+ *
16
+ * @category Navigation
17
+ * @platform mobile
18
+ */
19
+ const TabPanel = (0, react.memo)(function TabPanel({ tabId, children, style, ...viewProps }) {
20
+ const { selectedId } = require_components_Tabs_tabsContexts.useTabSelectionContext();
21
+ if (selectedId !== tabId) return null;
22
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
23
+ accessibilityRole: "none",
24
+ style,
25
+ ...viewProps,
26
+ children
27
+ });
28
+ });
29
+ TabPanel.displayName = "TabPanel";
30
+ //#endregion
31
+ exports.TabPanel = TabPanel;
@@ -0,0 +1,24 @@
1
+
2
+ import { UniversalTabPanelProps } from "../../types/dist/index.cjs";
3
+ import * as _$react from "react";
4
+ import { ViewProps, ViewStyle } from "react-native";
5
+
6
+ //#region src/components/Tabs/TabPanel.d.ts
7
+ interface TabPanelProps extends Omit<UniversalTabPanelProps, 'className'>, Omit<ViewProps, 'style' | 'children'> {
8
+ children: UniversalTabPanelProps['children'];
9
+ style?: ViewStyle;
10
+ }
11
+ /**
12
+ * **⚙️ TabPanel**
13
+ *
14
+ * @description
15
+ * Content associated with a tab id. Only the panel whose `tabId` matches the current
16
+ * selection is rendered.
17
+ *
18
+ * @category Navigation
19
+ * @platform mobile
20
+ */
21
+ declare const TabPanel: _$react.NamedExoticComponent<TabPanelProps>;
22
+ //#endregion
23
+ export { TabPanel, type TabPanelProps };
24
+ //# sourceMappingURL=TabPanel.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabPanel.d.cts","names":[],"sources":["../../../src/components/Tabs/TabPanel.tsx"],"mappings":";;;;;;UAOU,aAAA,SACA,IAAA,CAAK,sBAAA,gBAAsC,IAAA,CAAK,SAAA;EACxD,QAAA,EAAU,sBAAA;EACV,KAAA,GAAQ,SAAA;AAAA;;;;;;;;;;;cAaJ,QAAA,EAAQ,OAAA,CAAA,oBAAA,CAAA,aAAA"}
@@ -0,0 +1,24 @@
1
+
2
+ import { UniversalTabPanelProps } from "../../types/dist/index.js";
3
+ import * as _$react from "react";
4
+ import { ViewProps, ViewStyle } from "react-native";
5
+
6
+ //#region src/components/Tabs/TabPanel.d.ts
7
+ interface TabPanelProps extends Omit<UniversalTabPanelProps, 'className'>, Omit<ViewProps, 'style' | 'children'> {
8
+ children: UniversalTabPanelProps['children'];
9
+ style?: ViewStyle;
10
+ }
11
+ /**
12
+ * **⚙️ TabPanel**
13
+ *
14
+ * @description
15
+ * Content associated with a tab id. Only the panel whose `tabId` matches the current
16
+ * selection is rendered.
17
+ *
18
+ * @category Navigation
19
+ * @platform mobile
20
+ */
21
+ declare const TabPanel: _$react.NamedExoticComponent<TabPanelProps>;
22
+ //#endregion
23
+ export { TabPanel, type TabPanelProps };
24
+ //# sourceMappingURL=TabPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabPanel.d.ts","names":[],"sources":["../../../src/components/Tabs/TabPanel.tsx"],"mappings":";;;;;;UAOU,aAAA,SACA,IAAA,CAAK,sBAAA,gBAAsC,IAAA,CAAK,SAAA;EACxD,QAAA,EAAU,sBAAA;EACV,KAAA,GAAQ,SAAA;AAAA;;;;;;;;;;;cAaJ,QAAA,EAAQ,OAAA,CAAA,oBAAA,CAAA,aAAA"}