@oxyhq/bloom 0.35.3 → 0.35.4

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.
@@ -15,7 +15,8 @@ const TabsContext = /*#__PURE__*/(0, _react.createContext)({
15
15
  value: '',
16
16
  onValueChange: () => {},
17
17
  variant: 'underline',
18
- fullWidth: false
18
+ fullWidth: false,
19
+ reportTriggerLayout: () => {}
19
20
  });
20
21
  const TabsBarComponent = ({
21
22
  value,
@@ -27,12 +28,60 @@ const TabsBarComponent = ({
27
28
  testID
28
29
  }) => {
29
30
  const theme = (0, _useTheme.useTheme)();
31
+ const isUnderline = variant === 'underline';
32
+
33
+ // Shared sliding underline: one indicator that translates + resizes between
34
+ // triggers. Triggers report their measured {x, width}; the container drives
35
+ // these Animated values imperatively (no re-render on measure or slide).
36
+ const indicatorX = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
37
+ const indicatorWidth = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
38
+ const triggerLayoutsRef = (0, _react.useRef)({});
39
+ const indicatorPlacedRef = (0, _react.useRef)(false);
40
+ const moveIndicator = (0, _react.useCallback)((target, animate) => {
41
+ if (animate) {
42
+ _reactNative.Animated.parallel([_reactNative.Animated.timing(indicatorX, {
43
+ toValue: target.x,
44
+ duration: 200,
45
+ easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
46
+ useNativeDriver: false
47
+ }), _reactNative.Animated.timing(indicatorWidth, {
48
+ toValue: target.width,
49
+ duration: 200,
50
+ easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
51
+ useNativeDriver: false
52
+ })]).start();
53
+ } else {
54
+ indicatorX.setValue(target.x);
55
+ indicatorWidth.setValue(target.width);
56
+ }
57
+ }, [indicatorX, indicatorWidth]);
58
+ const reportTriggerLayout = (0, _react.useCallback)((tabValue, layout) => {
59
+ triggerLayoutsRef.current[tabValue] = layout;
60
+ // Snap onto the active trigger the moment it's first measured (mount) or
61
+ // when its size changes — never slide in from the origin.
62
+ if (tabValue === value) {
63
+ moveIndicator(layout, false);
64
+ indicatorPlacedRef.current = true;
65
+ }
66
+ }, [value, moveIndicator]);
67
+
68
+ // Slide the indicator to the newly-selected trigger. Syncing an imperative
69
+ // Animated value to the controlled `value` prop is a legitimate effect
70
+ // (external-system sync); the first placement snaps, later changes animate.
71
+ (0, _react.useEffect)(() => {
72
+ if (!isUnderline) return;
73
+ const target = triggerLayoutsRef.current[value];
74
+ if (!target) return; // not measured yet — reportTriggerLayout will place it
75
+ moveIndicator(target, indicatorPlacedRef.current);
76
+ indicatorPlacedRef.current = true;
77
+ }, [value, isUnderline, moveIndicator]);
30
78
  const contextValue = (0, _react.useMemo)(() => ({
31
79
  value,
32
80
  onValueChange,
33
81
  variant,
34
- fullWidth
35
- }), [value, onValueChange, variant, fullWidth]);
82
+ fullWidth,
83
+ reportTriggerLayout
84
+ }), [value, onValueChange, variant, fullWidth, reportTriggerLayout]);
36
85
  const containerStyle = (0, _react.useMemo)(() => {
37
86
  const base = {
38
87
  flexDirection: 'row',
@@ -57,18 +106,33 @@ const TabsBarComponent = ({
57
106
  }
58
107
  return base;
59
108
  }, [variant, theme]);
109
+ const indicator = isUnderline ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
110
+ pointerEvents: "none",
111
+ testID: testID ? `${testID}-indicator` : undefined,
112
+ style: {
113
+ position: 'absolute',
114
+ left: 0,
115
+ bottom: 0,
116
+ height: 2,
117
+ backgroundColor: theme.colors.primary,
118
+ width: indicatorWidth,
119
+ transform: [{
120
+ translateX: indicatorX
121
+ }]
122
+ }
123
+ }) : null;
60
124
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(TabsContext.Provider, {
61
125
  value: contextValue,
62
- children: fullWidth ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
126
+ children: fullWidth ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
63
127
  style: [containerStyle, style],
64
128
  testID: testID,
65
- children: children
66
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
129
+ children: [children, indicator]
130
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
67
131
  horizontal: true,
68
132
  showsHorizontalScrollIndicator: false,
69
133
  contentContainerStyle: [containerStyle, style],
70
134
  testID: testID,
71
- children: children
135
+ children: [children, indicator]
72
136
  })
73
137
  });
74
138
  };
@@ -85,7 +149,8 @@ const TabComponent = ({
85
149
  value: selectedValue,
86
150
  onValueChange,
87
151
  variant,
88
- fullWidth
152
+ fullWidth,
153
+ reportTriggerLayout
89
154
  } = (0, _react.useContext)(TabsContext);
90
155
  const isSelected = value === selectedValue;
91
156
  const {
@@ -109,11 +174,8 @@ const TabComponent = ({
109
174
  };
110
175
  switch (variant) {
111
176
  case 'underline':
112
- if (isSelected) {
113
- base.borderBottomWidth = 2;
114
- base.borderBottomColor = theme.colors.primary;
115
- base.marginBottom = -1; // overlap container border
116
- }
177
+ // Active state is drawn by the shared sliding indicator, not a
178
+ // per-trigger border — nothing to add here.
117
179
  break;
118
180
  case 'filled':
119
181
  if (isSelected) {
@@ -153,6 +215,16 @@ const TabComponent = ({
153
215
  return base;
154
216
  }, [variant, isSelected, theme]);
155
217
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
218
+ onLayout: e => {
219
+ const {
220
+ x,
221
+ width
222
+ } = e.nativeEvent.layout;
223
+ reportTriggerLayout(value, {
224
+ x,
225
+ width
226
+ });
227
+ },
156
228
  style: [{
157
229
  transform: [{
158
230
  scale: scaleAnim
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_useTheme","_usePressAnimation","_tokens","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","TabsContext","createContext","value","onValueChange","variant","fullWidth","TabsBarComponent","children","style","testID","theme","useTheme","contextValue","useMemo","containerStyle","base","flexDirection","alignItems","borderBottomWidth","borderBottomColor","colors","borderLight","backgroundColor","backgroundSecondary","borderRadius","sm","padding","borderWidth","borderColor","border","jsx","Provider","View","ScrollView","horizontal","showsHorizontalScrollIndicator","contentContainerStyle","TabComponent","label","icon","disabled","textStyle","selectedValue","useContext","isSelected","scaleAnim","onPressIn","onPressOut","usePressAnimation","handlePress","useCallback","tabStyle","justifyContent","paddingHorizontal","space","lg","paddingVertical","gap","xs","primary","marginBottom","card","shadowColor","shadow","shadowOffset","width","height","shadowOpacity","shadowRadius","elevation","labelStyle","fontSize","fontWeight","color","primaryForeground","textSecondary","Animated","transform","scale","flex","jsxs","Pressable","opacity","onPress","accessibilityRole","accessibilityState","selected","Text","TabPanelComponent","Tabs","exports","memo","displayName","TabsTrigger","TabsContent"],"sourceRoot":"../../../src","sources":["tabs/Tabs.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_useTheme","_usePressAnimation","_tokens","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","TabsContext","createContext","value","onValueChange","variant","fullWidth","reportTriggerLayout","TabsBarComponent","children","style","testID","theme","useTheme","isUnderline","indicatorX","useRef","Animated","Value","current","indicatorWidth","triggerLayoutsRef","indicatorPlacedRef","moveIndicator","useCallback","target","animate","parallel","timing","toValue","x","duration","easing","Easing","out","cubic","useNativeDriver","width","start","setValue","tabValue","layout","useEffect","contextValue","useMemo","containerStyle","base","flexDirection","alignItems","borderBottomWidth","borderBottomColor","colors","borderLight","backgroundColor","backgroundSecondary","borderRadius","sm","padding","borderWidth","borderColor","border","indicator","jsx","View","pointerEvents","undefined","position","left","bottom","height","primary","transform","translateX","Provider","jsxs","ScrollView","horizontal","showsHorizontalScrollIndicator","contentContainerStyle","TabComponent","label","icon","disabled","textStyle","selectedValue","useContext","isSelected","scaleAnim","onPressIn","onPressOut","usePressAnimation","handlePress","tabStyle","justifyContent","paddingHorizontal","space","lg","paddingVertical","gap","xs","card","shadowColor","shadow","shadowOffset","shadowOpacity","shadowRadius","elevation","labelStyle","fontSize","fontWeight","color","primaryForeground","textSecondary","onLayout","nativeEvent","scale","flex","Pressable","opacity","onPress","accessibilityRole","accessibilityState","selected","Text","TabPanelComponent","Tabs","exports","memo","displayName","TabsTrigger","TabsContent"],"sourceRoot":"../../../src","sources":["tabs/Tabs.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
- import React, { createContext, memo, useCallback, useContext, useMemo } from 'react';
4
- import { View, Text, Pressable, Animated, ScrollView } from 'react-native';
3
+ import React, { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
4
+ import { View, Text, Pressable, Animated, Easing, ScrollView } from 'react-native';
5
5
  import { useTheme } from "../theme/use-theme.js";
6
6
  import { usePressAnimation } from "../hooks/usePressAnimation.js";
7
7
  import { borderRadius, space } from "../styles/tokens.js";
@@ -10,7 +10,8 @@ const TabsContext = /*#__PURE__*/createContext({
10
10
  value: '',
11
11
  onValueChange: () => {},
12
12
  variant: 'underline',
13
- fullWidth: false
13
+ fullWidth: false,
14
+ reportTriggerLayout: () => {}
14
15
  });
15
16
  const TabsBarComponent = ({
16
17
  value,
@@ -22,12 +23,60 @@ const TabsBarComponent = ({
22
23
  testID
23
24
  }) => {
24
25
  const theme = useTheme();
26
+ const isUnderline = variant === 'underline';
27
+
28
+ // Shared sliding underline: one indicator that translates + resizes between
29
+ // triggers. Triggers report their measured {x, width}; the container drives
30
+ // these Animated values imperatively (no re-render on measure or slide).
31
+ const indicatorX = useRef(new Animated.Value(0)).current;
32
+ const indicatorWidth = useRef(new Animated.Value(0)).current;
33
+ const triggerLayoutsRef = useRef({});
34
+ const indicatorPlacedRef = useRef(false);
35
+ const moveIndicator = useCallback((target, animate) => {
36
+ if (animate) {
37
+ Animated.parallel([Animated.timing(indicatorX, {
38
+ toValue: target.x,
39
+ duration: 200,
40
+ easing: Easing.out(Easing.cubic),
41
+ useNativeDriver: false
42
+ }), Animated.timing(indicatorWidth, {
43
+ toValue: target.width,
44
+ duration: 200,
45
+ easing: Easing.out(Easing.cubic),
46
+ useNativeDriver: false
47
+ })]).start();
48
+ } else {
49
+ indicatorX.setValue(target.x);
50
+ indicatorWidth.setValue(target.width);
51
+ }
52
+ }, [indicatorX, indicatorWidth]);
53
+ const reportTriggerLayout = useCallback((tabValue, layout) => {
54
+ triggerLayoutsRef.current[tabValue] = layout;
55
+ // Snap onto the active trigger the moment it's first measured (mount) or
56
+ // when its size changes — never slide in from the origin.
57
+ if (tabValue === value) {
58
+ moveIndicator(layout, false);
59
+ indicatorPlacedRef.current = true;
60
+ }
61
+ }, [value, moveIndicator]);
62
+
63
+ // Slide the indicator to the newly-selected trigger. Syncing an imperative
64
+ // Animated value to the controlled `value` prop is a legitimate effect
65
+ // (external-system sync); the first placement snaps, later changes animate.
66
+ useEffect(() => {
67
+ if (!isUnderline) return;
68
+ const target = triggerLayoutsRef.current[value];
69
+ if (!target) return; // not measured yet — reportTriggerLayout will place it
70
+ moveIndicator(target, indicatorPlacedRef.current);
71
+ indicatorPlacedRef.current = true;
72
+ }, [value, isUnderline, moveIndicator]);
25
73
  const contextValue = useMemo(() => ({
26
74
  value,
27
75
  onValueChange,
28
76
  variant,
29
- fullWidth
30
- }), [value, onValueChange, variant, fullWidth]);
77
+ fullWidth,
78
+ reportTriggerLayout
79
+ }), [value, onValueChange, variant, fullWidth, reportTriggerLayout]);
31
80
  const containerStyle = useMemo(() => {
32
81
  const base = {
33
82
  flexDirection: 'row',
@@ -52,18 +101,33 @@ const TabsBarComponent = ({
52
101
  }
53
102
  return base;
54
103
  }, [variant, theme]);
104
+ const indicator = isUnderline ? /*#__PURE__*/_jsx(Animated.View, {
105
+ pointerEvents: "none",
106
+ testID: testID ? `${testID}-indicator` : undefined,
107
+ style: {
108
+ position: 'absolute',
109
+ left: 0,
110
+ bottom: 0,
111
+ height: 2,
112
+ backgroundColor: theme.colors.primary,
113
+ width: indicatorWidth,
114
+ transform: [{
115
+ translateX: indicatorX
116
+ }]
117
+ }
118
+ }) : null;
55
119
  return /*#__PURE__*/_jsx(TabsContext.Provider, {
56
120
  value: contextValue,
57
- children: fullWidth ? /*#__PURE__*/_jsx(View, {
121
+ children: fullWidth ? /*#__PURE__*/_jsxs(View, {
58
122
  style: [containerStyle, style],
59
123
  testID: testID,
60
- children: children
61
- }) : /*#__PURE__*/_jsx(ScrollView, {
124
+ children: [children, indicator]
125
+ }) : /*#__PURE__*/_jsxs(ScrollView, {
62
126
  horizontal: true,
63
127
  showsHorizontalScrollIndicator: false,
64
128
  contentContainerStyle: [containerStyle, style],
65
129
  testID: testID,
66
- children: children
130
+ children: [children, indicator]
67
131
  })
68
132
  });
69
133
  };
@@ -80,7 +144,8 @@ const TabComponent = ({
80
144
  value: selectedValue,
81
145
  onValueChange,
82
146
  variant,
83
- fullWidth
147
+ fullWidth,
148
+ reportTriggerLayout
84
149
  } = useContext(TabsContext);
85
150
  const isSelected = value === selectedValue;
86
151
  const {
@@ -104,11 +169,8 @@ const TabComponent = ({
104
169
  };
105
170
  switch (variant) {
106
171
  case 'underline':
107
- if (isSelected) {
108
- base.borderBottomWidth = 2;
109
- base.borderBottomColor = theme.colors.primary;
110
- base.marginBottom = -1; // overlap container border
111
- }
172
+ // Active state is drawn by the shared sliding indicator, not a
173
+ // per-trigger border — nothing to add here.
112
174
  break;
113
175
  case 'filled':
114
176
  if (isSelected) {
@@ -148,6 +210,16 @@ const TabComponent = ({
148
210
  return base;
149
211
  }, [variant, isSelected, theme]);
150
212
  return /*#__PURE__*/_jsx(Animated.View, {
213
+ onLayout: e => {
214
+ const {
215
+ x,
216
+ width
217
+ } = e.nativeEvent.layout;
218
+ reportTriggerLayout(value, {
219
+ x,
220
+ width
221
+ });
222
+ },
151
223
  style: [{
152
224
  transform: [{
153
225
  scale: scaleAnim
@@ -1 +1 @@
1
- {"version":3,"names":["React","createContext","memo","useCallback","useContext","useMemo","View","Text","Pressable","Animated","ScrollView","useTheme","usePressAnimation","borderRadius","space","jsx","_jsx","jsxs","_jsxs","TabsContext","value","onValueChange","variant","fullWidth","TabsBarComponent","children","style","testID","theme","contextValue","containerStyle","base","flexDirection","alignItems","borderBottomWidth","borderBottomColor","colors","borderLight","backgroundColor","backgroundSecondary","sm","padding","borderWidth","borderColor","border","Provider","horizontal","showsHorizontalScrollIndicator","contentContainerStyle","TabComponent","label","icon","disabled","textStyle","selectedValue","isSelected","scaleAnim","onPressIn","onPressOut","handlePress","tabStyle","justifyContent","paddingHorizontal","lg","paddingVertical","gap","xs","primary","marginBottom","card","shadowColor","shadow","shadowOffset","width","height","shadowOpacity","shadowRadius","elevation","labelStyle","fontSize","fontWeight","color","primaryForeground","textSecondary","transform","scale","flex","opacity","onPress","accessibilityRole","accessibilityState","selected","TabPanelComponent","Tabs","displayName","TabsTrigger","TabsContent"],"sourceRoot":"../../../src","sources":["tabs/Tabs.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","createContext","memo","useCallback","useContext","useEffect","useMemo","useRef","View","Text","Pressable","Animated","Easing","ScrollView","useTheme","usePressAnimation","borderRadius","space","jsx","_jsx","jsxs","_jsxs","TabsContext","value","onValueChange","variant","fullWidth","reportTriggerLayout","TabsBarComponent","children","style","testID","theme","isUnderline","indicatorX","Value","current","indicatorWidth","triggerLayoutsRef","indicatorPlacedRef","moveIndicator","target","animate","parallel","timing","toValue","x","duration","easing","out","cubic","useNativeDriver","width","start","setValue","tabValue","layout","contextValue","containerStyle","base","flexDirection","alignItems","borderBottomWidth","borderBottomColor","colors","borderLight","backgroundColor","backgroundSecondary","sm","padding","borderWidth","borderColor","border","indicator","pointerEvents","undefined","position","left","bottom","height","primary","transform","translateX","Provider","horizontal","showsHorizontalScrollIndicator","contentContainerStyle","TabComponent","label","icon","disabled","textStyle","selectedValue","isSelected","scaleAnim","onPressIn","onPressOut","handlePress","tabStyle","justifyContent","paddingHorizontal","lg","paddingVertical","gap","xs","card","shadowColor","shadow","shadowOffset","shadowOpacity","shadowRadius","elevation","labelStyle","fontSize","fontWeight","color","primaryForeground","textSecondary","onLayout","e","nativeEvent","scale","flex","opacity","onPress","accessibilityRole","accessibilityState","selected","TabPanelComponent","Tabs","displayName","TabsTrigger","TabsContent"],"sourceRoot":"../../../src","sources":["tabs/Tabs.tsx"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../src/tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAcf,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAe,MAAM,SAAS,CAAC;AA4L1F,eAAO,MAAM,IAAI,uCAAyB,CAAC;AAG3C,eAAO,MAAM,WAAW,8CAAqB,CAAC;AAG9C,eAAO,MAAM,WAAW,8CAA0B,CAAC"}
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../src/tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAe,MAAM,SAAS,CAAC;AA+Q1F,eAAO,MAAM,IAAI,uCAAyB,CAAC;AAG3C,eAAO,MAAM,WAAW,8CAAqB,CAAC;AAG9C,eAAO,MAAM,WAAW,8CAA0B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../src/tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAcf,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAe,MAAM,SAAS,CAAC;AA4L1F,eAAO,MAAM,IAAI,uCAAyB,CAAC;AAG3C,eAAO,MAAM,WAAW,8CAAqB,CAAC;AAG9C,eAAO,MAAM,WAAW,8CAA0B,CAAC"}
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../src/tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAe,MAAM,SAAS,CAAC;AA+Q1F,eAAO,MAAM,IAAI,uCAAyB,CAAC;AAG3C,eAAO,MAAM,WAAW,8CAAqB,CAAC;AAG9C,eAAO,MAAM,WAAW,8CAA0B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/bloom",
3
- "version": "0.35.3",
3
+ "version": "0.35.4",
4
4
  "description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -0,0 +1,110 @@
1
+ import React from 'react';
2
+ import type { ReactTestInstance } from 'react-test-renderer';
3
+ import { fireEvent, render } from '@testing-library/react-native';
4
+
5
+ import { BloomThemeProvider } from '../theme/BloomThemeProvider';
6
+ import { Tabs, TabsTrigger } from '../tabs';
7
+
8
+ function renderWithTheme(ui: React.ReactElement) {
9
+ return render(
10
+ <BloomThemeProvider mode="light" colorPreset="teal">
11
+ {ui}
12
+ </BloomThemeProvider>,
13
+ );
14
+ }
15
+
16
+ // Flatten a (possibly nested / conditional) RN style prop into one object.
17
+ function flattenStyle(style: unknown): Record<string, unknown> {
18
+ const out: Record<string, unknown> = {};
19
+ const visit = (s: unknown): void => {
20
+ if (Array.isArray(s)) s.forEach(visit);
21
+ else if (s && typeof s === 'object') Object.assign(out, s);
22
+ };
23
+ visit(style);
24
+ return out;
25
+ }
26
+
27
+ // Walk up from a label's Text node to the trigger Pressable (role="tab").
28
+ function triggerFor(node: ReactTestInstance): ReactTestInstance {
29
+ let current: ReactTestInstance | null = node;
30
+ while (current && current.props?.accessibilityRole !== 'tab') {
31
+ current = current.parent;
32
+ }
33
+ if (!current) throw new Error('No trigger ancestor with role "tab" found');
34
+ return current;
35
+ }
36
+
37
+ function Bar({
38
+ value,
39
+ onValueChange = () => {},
40
+ ...props
41
+ }: {
42
+ value: string;
43
+ onValueChange?: (v: string) => void;
44
+ } & Partial<React.ComponentProps<typeof Tabs>>) {
45
+ return (
46
+ <Tabs value={value} onValueChange={onValueChange} testID="tabs" {...props}>
47
+ <TabsTrigger value="a" label="First" />
48
+ <TabsTrigger value="b" label="Second" />
49
+ </Tabs>
50
+ );
51
+ }
52
+
53
+ describe('Tabs', () => {
54
+ it('renders trigger labels', () => {
55
+ const { getByText } = renderWithTheme(<Bar value="a" />);
56
+ expect(getByText('First')).toBeTruthy();
57
+ expect(getByText('Second')).toBeTruthy();
58
+ });
59
+
60
+ it('calls onValueChange when a trigger is pressed', () => {
61
+ const onValueChange = jest.fn();
62
+ const { getByText } = renderWithTheme(
63
+ <Bar value="a" onValueChange={onValueChange} />,
64
+ );
65
+ fireEvent.press(getByText('Second'));
66
+ expect(onValueChange).toHaveBeenCalledWith('b');
67
+ });
68
+
69
+ it('renders exactly one shared underline indicator, not per-trigger borders', () => {
70
+ const { getByTestId, getByText } = renderWithTheme(<Bar value="a" />);
71
+ // One shared indicator element...
72
+ expect(getByTestId('tabs-indicator')).toBeTruthy();
73
+ // ...and no trigger draws the old static active bottom border.
74
+ for (const label of ['First', 'Second']) {
75
+ const trigger = triggerFor(getByText(label));
76
+ expect(flattenStyle(trigger.props.style).borderBottomWidth).toBeUndefined();
77
+ }
78
+ });
79
+
80
+ it('does not render the underline indicator for the filled variant', () => {
81
+ const { queryByTestId } = renderWithTheme(<Bar value="a" variant="filled" />);
82
+ expect(queryByTestId('tabs-indicator')).toBeNull();
83
+ });
84
+
85
+ it('stretches each trigger to equal width when fullWidth is set', () => {
86
+ const { getByText } = renderWithTheme(<Bar value="a" fullWidth />);
87
+ for (const label of ['First', 'Second']) {
88
+ expect(flattenStyle(triggerFor(getByText(label)).props.style).flex).toBe(1);
89
+ }
90
+ });
91
+
92
+ it('keeps triggers content-sized (no flex) by default', () => {
93
+ const { getByText } = renderWithTheme(<Bar value="a" />);
94
+ for (const label of ['First', 'Second']) {
95
+ expect(
96
+ flattenStyle(triggerFor(getByText(label)).props.style).flex,
97
+ ).toBeUndefined();
98
+ }
99
+ });
100
+
101
+ it('marks the active trigger as selected for accessibility', () => {
102
+ const { getByText } = renderWithTheme(<Bar value="b" />);
103
+ expect(
104
+ triggerFor(getByText('First')).props.accessibilityState.selected,
105
+ ).toBe(false);
106
+ expect(
107
+ triggerFor(getByText('Second')).props.accessibilityState.selected,
108
+ ).toBe(true);
109
+ });
110
+ });
package/src/tabs/Tabs.tsx CHANGED
@@ -3,14 +3,18 @@ import React, {
3
3
  memo,
4
4
  useCallback,
5
5
  useContext,
6
+ useEffect,
6
7
  useMemo,
8
+ useRef,
7
9
  } from 'react';
8
10
  import {
9
11
  View,
10
12
  Text,
11
13
  Pressable,
12
14
  Animated,
15
+ Easing,
13
16
  ScrollView,
17
+ type LayoutRectangle,
14
18
  type ViewStyle,
15
19
  type TextStyle,
16
20
  } from 'react-native';
@@ -20,11 +24,15 @@ import { usePressAnimation } from '../hooks/usePressAnimation';
20
24
  import { borderRadius, space } from '../styles/tokens';
21
25
  import type { TabsProps, TabsTriggerProps, TabsContentProps, TabsVariant } from './types';
22
26
 
27
+ type TriggerLayout = Pick<LayoutRectangle, 'x' | 'width'>;
28
+
23
29
  interface TabsContextValue {
24
30
  value: string;
25
31
  onValueChange: (value: string) => void;
26
32
  variant: TabsVariant;
27
33
  fullWidth: boolean;
34
+ /** A trigger reports its measured position so the shared underline can track it. */
35
+ reportTriggerLayout: (value: string, layout: TriggerLayout) => void;
28
36
  }
29
37
 
30
38
  const TabsContext = createContext<TabsContextValue>({
@@ -32,6 +40,7 @@ const TabsContext = createContext<TabsContextValue>({
32
40
  onValueChange: () => {},
33
41
  variant: 'underline',
34
42
  fullWidth: false,
43
+ reportTriggerLayout: () => {},
35
44
  });
36
45
 
37
46
  const TabsBarComponent: React.FC<TabsProps> = ({
@@ -44,10 +53,68 @@ const TabsBarComponent: React.FC<TabsProps> = ({
44
53
  testID,
45
54
  }) => {
46
55
  const theme = useTheme();
56
+ const isUnderline = variant === 'underline';
57
+
58
+ // Shared sliding underline: one indicator that translates + resizes between
59
+ // triggers. Triggers report their measured {x, width}; the container drives
60
+ // these Animated values imperatively (no re-render on measure or slide).
61
+ const indicatorX = useRef(new Animated.Value(0)).current;
62
+ const indicatorWidth = useRef(new Animated.Value(0)).current;
63
+ const triggerLayoutsRef = useRef<Record<string, TriggerLayout>>({});
64
+ const indicatorPlacedRef = useRef(false);
65
+
66
+ const moveIndicator = useCallback(
67
+ (target: TriggerLayout, animate: boolean) => {
68
+ if (animate) {
69
+ Animated.parallel([
70
+ Animated.timing(indicatorX, {
71
+ toValue: target.x,
72
+ duration: 200,
73
+ easing: Easing.out(Easing.cubic),
74
+ useNativeDriver: false,
75
+ }),
76
+ Animated.timing(indicatorWidth, {
77
+ toValue: target.width,
78
+ duration: 200,
79
+ easing: Easing.out(Easing.cubic),
80
+ useNativeDriver: false,
81
+ }),
82
+ ]).start();
83
+ } else {
84
+ indicatorX.setValue(target.x);
85
+ indicatorWidth.setValue(target.width);
86
+ }
87
+ },
88
+ [indicatorX, indicatorWidth],
89
+ );
90
+
91
+ const reportTriggerLayout = useCallback(
92
+ (tabValue: string, layout: TriggerLayout) => {
93
+ triggerLayoutsRef.current[tabValue] = layout;
94
+ // Snap onto the active trigger the moment it's first measured (mount) or
95
+ // when its size changes — never slide in from the origin.
96
+ if (tabValue === value) {
97
+ moveIndicator(layout, false);
98
+ indicatorPlacedRef.current = true;
99
+ }
100
+ },
101
+ [value, moveIndicator],
102
+ );
103
+
104
+ // Slide the indicator to the newly-selected trigger. Syncing an imperative
105
+ // Animated value to the controlled `value` prop is a legitimate effect
106
+ // (external-system sync); the first placement snaps, later changes animate.
107
+ useEffect(() => {
108
+ if (!isUnderline) return;
109
+ const target = triggerLayoutsRef.current[value];
110
+ if (!target) return; // not measured yet — reportTriggerLayout will place it
111
+ moveIndicator(target, indicatorPlacedRef.current);
112
+ indicatorPlacedRef.current = true;
113
+ }, [value, isUnderline, moveIndicator]);
47
114
 
48
115
  const contextValue = useMemo(
49
- () => ({ value, onValueChange, variant, fullWidth }),
50
- [value, onValueChange, variant, fullWidth],
116
+ () => ({ value, onValueChange, variant, fullWidth, reportTriggerLayout }),
117
+ [value, onValueChange, variant, fullWidth, reportTriggerLayout],
51
118
  );
52
119
 
53
120
  const containerStyle = useMemo((): ViewStyle => {
@@ -77,11 +144,28 @@ const TabsBarComponent: React.FC<TabsProps> = ({
77
144
  return base;
78
145
  }, [variant, theme]);
79
146
 
147
+ const indicator = isUnderline ? (
148
+ <Animated.View
149
+ pointerEvents="none"
150
+ testID={testID ? `${testID}-indicator` : undefined}
151
+ style={{
152
+ position: 'absolute',
153
+ left: 0,
154
+ bottom: 0,
155
+ height: 2,
156
+ backgroundColor: theme.colors.primary,
157
+ width: indicatorWidth,
158
+ transform: [{ translateX: indicatorX }],
159
+ }}
160
+ />
161
+ ) : null;
162
+
80
163
  return (
81
164
  <TabsContext.Provider value={contextValue}>
82
165
  {fullWidth ? (
83
166
  <View style={[containerStyle, style]} testID={testID}>
84
167
  {children}
168
+ {indicator}
85
169
  </View>
86
170
  ) : (
87
171
  <ScrollView
@@ -91,6 +175,7 @@ const TabsBarComponent: React.FC<TabsProps> = ({
91
175
  testID={testID}
92
176
  >
93
177
  {children}
178
+ {indicator}
94
179
  </ScrollView>
95
180
  )}
96
181
  </TabsContext.Provider>
@@ -111,6 +196,7 @@ const TabComponent: React.FC<TabsTriggerProps> = ({
111
196
  onValueChange,
112
197
  variant,
113
198
  fullWidth,
199
+ reportTriggerLayout,
114
200
  } = useContext(TabsContext);
115
201
  const isSelected = value === selectedValue;
116
202
  const { scaleAnim, onPressIn, onPressOut } = usePressAnimation(0.97);
@@ -133,11 +219,8 @@ const TabComponent: React.FC<TabsTriggerProps> = ({
133
219
 
134
220
  switch (variant) {
135
221
  case 'underline':
136
- if (isSelected) {
137
- base.borderBottomWidth = 2;
138
- base.borderBottomColor = theme.colors.primary;
139
- base.marginBottom = -1; // overlap container border
140
- }
222
+ // Active state is drawn by the shared sliding indicator, not a
223
+ // per-trigger border — nothing to add here.
141
224
  break;
142
225
  case 'filled':
143
226
  if (isSelected) {
@@ -180,6 +263,10 @@ const TabComponent: React.FC<TabsTriggerProps> = ({
180
263
 
181
264
  return (
182
265
  <Animated.View
266
+ onLayout={(e) => {
267
+ const { x, width } = e.nativeEvent.layout;
268
+ reportTriggerLayout(value, { x, width });
269
+ }}
183
270
  style={[{ transform: [{ scale: scaleAnim }] }, fullWidth && { flex: 1 }]}
184
271
  >
185
272
  <Pressable