@cdx-ui/components 0.2.3 → 0.2.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.
Files changed (248) hide show
  1. package/AGENTS.md +24 -0
  2. package/README.md +2 -0
  3. package/coverage.svg +1 -1
  4. package/docs/components/accordion/content.md +538 -0
  5. package/docs/components/alert/content.md +203 -0
  6. package/docs/components/alert-dialog/content.md +319 -0
  7. package/docs/components/avatar/content.md +368 -0
  8. package/docs/components/avatar/design.md +202 -0
  9. package/docs/components/badge/content.md +235 -0
  10. package/docs/components/bottom-sheet/content.md +351 -0
  11. package/docs/components/bottom-sheet/design.md +249 -0
  12. package/docs/components/breadcrumbs/content.md +169 -0
  13. package/docs/components/button/content.md +398 -0
  14. package/docs/components/button/design.md +258 -0
  15. package/docs/components/calendar/content.md +137 -0
  16. package/docs/components/card/content.md +283 -0
  17. package/docs/components/carousel/content.md +416 -0
  18. package/docs/components/checkbox/content.md +236 -0
  19. package/docs/components/checkbox/design.md +214 -0
  20. package/docs/components/chip/content.md +439 -0
  21. package/docs/components/chip/design.md +418 -0
  22. package/docs/components/color-area/content.md +86 -0
  23. package/docs/components/color-field/content.md +134 -0
  24. package/docs/components/color-picker/content.md +208 -0
  25. package/docs/components/color-slider/content.md +120 -0
  26. package/docs/components/color-swatch/content.md +64 -0
  27. package/docs/components/color-swatch-picker/content.md +126 -0
  28. package/docs/components/content.md +97 -0
  29. package/docs/components/currency-input/content.md +205 -0
  30. package/docs/components/data-grid/content.md +522 -0
  31. package/docs/components/date-field/content.md +147 -0
  32. package/docs/components/date-picker/content.md +360 -0
  33. package/docs/components/date-range-picker/content.md +301 -0
  34. package/docs/components/date-time-field/content.md +157 -0
  35. package/docs/components/date-time-list/content.md +105 -0
  36. package/docs/components/date-time-picker/content.md +272 -0
  37. package/docs/components/dialog/content.md +436 -0
  38. package/docs/components/dialog/design.md +192 -0
  39. package/docs/components/divider/content.md +112 -0
  40. package/docs/components/drawer/content.md +436 -0
  41. package/docs/components/field/content.md +277 -0
  42. package/docs/components/form/content.md +62 -0
  43. package/docs/components/full-screen-dialog/content.md +881 -0
  44. package/docs/components/heading/content.md +55 -0
  45. package/docs/components/icon/content.md +190 -0
  46. package/docs/components/icon-button/content.md +200 -0
  47. package/docs/components/icon-button/design.md +165 -0
  48. package/docs/components/image/content.md +104 -0
  49. package/docs/components/input/content.md +281 -0
  50. package/docs/components/input/design.md +389 -0
  51. package/docs/components/insurance-disclosure/content.md +103 -0
  52. package/docs/components/link/content.md +180 -0
  53. package/docs/components/link/design.md +160 -0
  54. package/docs/components/list-item/content.md +695 -0
  55. package/docs/components/menu/content.md +1247 -0
  56. package/docs/components/month-calendar/content.md +84 -0
  57. package/docs/components/month-picker/content.md +273 -0
  58. package/docs/components/otp-input/content.md +327 -0
  59. package/docs/components/progress-bar/content.md +87 -0
  60. package/docs/components/progress-circle/content.md +176 -0
  61. package/docs/components/progress-segmented/content.md +119 -0
  62. package/docs/components/quick-action-button/content.md +154 -0
  63. package/docs/components/quick-action-button/design.md +170 -0
  64. package/docs/components/radio/content.md +224 -0
  65. package/docs/components/range-calendar/content.md +123 -0
  66. package/docs/components/reorderable-list/content.md +309 -0
  67. package/docs/components/scoped-theme/content.md +47 -0
  68. package/docs/components/scroll-shadow/content.md +686 -0
  69. package/docs/components/select/content.md +400 -0
  70. package/docs/components/select/design.md +301 -0
  71. package/docs/components/skeleton/content.md +103 -0
  72. package/docs/components/slider/content.md +423 -0
  73. package/docs/components/stack/content.md +161 -0
  74. package/docs/components/switch/content.md +150 -0
  75. package/docs/components/switch/design.md +208 -0
  76. package/docs/components/table/content.md +548 -0
  77. package/docs/components/table-pagination/content.md +177 -0
  78. package/docs/components/tabs/content.md +292 -0
  79. package/docs/components/text/content.md +142 -0
  80. package/docs/components/textarea/content.md +222 -0
  81. package/docs/components/tile/content.md +703 -0
  82. package/docs/components/toast/content.md +456 -0
  83. package/docs/components/toggle-button/content.md +505 -0
  84. package/docs/components/tooltip/content.md +350 -0
  85. package/docs/components/virtualized-list/content.md +250 -0
  86. package/docs/foundations/content.md +9 -0
  87. package/docs/foundations/expressions/icons/content.md +19 -0
  88. package/docs/foundations/styles/tokens/all-tokens/content.md +192 -0
  89. package/docs/foundations/styles/tokens/what-are-tokens/content.md +33 -0
  90. package/docs/foundations/styles/tokens/what-are-tokens/design.md +33 -0
  91. package/docs/getting-started/content.md +4 -0
  92. package/docs/getting-started/designers/content.md +13 -0
  93. package/docs/getting-started/designers/design.md +13 -0
  94. package/docs/getting-started/developers/accessibility/content.md +31 -0
  95. package/docs/getting-started/developers/content.md +612 -0
  96. package/docs/getting-started/developers/styling/content.md +193 -0
  97. package/docs/llms.txt +193 -0
  98. package/docs/patterns/account-management/content.md +75 -0
  99. package/docs/patterns/authentication/content.md +52 -0
  100. package/docs/patterns/content.md +10 -0
  101. package/docs/patterns/dashboard/content.md +39 -0
  102. package/docs/patterns/empty-states/content.md +31 -0
  103. package/docs/patterns/forms/content.md +109 -0
  104. package/docs/patterns/onboarding/content.md +69 -0
  105. package/docs/patterns/payments/content.md +35 -0
  106. package/docs/patterns/settings/content.md +72 -0
  107. package/docs/resources/content.md +9 -0
  108. package/docs/resources/figma-libraries/content.md +42 -0
  109. package/docs/resources/release-notes/0.0.1-beta.118/content.md +27 -0
  110. package/docs/resources/release-notes/0.0.1-beta.122/content.md +21 -0
  111. package/docs/resources/release-notes/0.0.1-beta.124/content.md +16 -0
  112. package/docs/resources/release-notes/0.0.1-beta.126/content.md +10 -0
  113. package/docs/resources/release-notes/0.0.1-beta.127/content.md +14 -0
  114. package/docs/resources/release-notes/0.0.1-beta.128/content.md +9 -0
  115. package/docs/resources/release-notes/0.0.1-beta.129/content.md +18 -0
  116. package/docs/resources/release-notes/0.0.1-beta.130/content.md +18 -0
  117. package/docs/resources/release-notes/0.0.1-beta.133/content.md +7 -0
  118. package/docs/resources/release-notes/0.0.1-beta.134/content.md +17 -0
  119. package/docs/resources/release-notes/0.0.1-beta.136/content.md +7 -0
  120. package/docs/resources/release-notes/0.0.1-beta.137/content.md +10 -0
  121. package/docs/resources/release-notes/0.0.1-beta.138/content.md +7 -0
  122. package/docs/resources/release-notes/0.0.1-beta.139/content.md +13 -0
  123. package/docs/resources/release-notes/0.0.1-beta.140/content.md +26 -0
  124. package/docs/resources/release-notes/0.0.1-beta.141/content.md +63 -0
  125. package/docs/resources/release-notes/0.0.1-beta.142/content.md +7 -0
  126. package/docs/resources/release-notes/0.0.1-beta.143/content.md +12 -0
  127. package/docs/resources/release-notes/0.0.1-beta.144/content.md +7 -0
  128. package/docs/resources/release-notes/0.0.1-beta.145/content.md +7 -0
  129. package/docs/resources/release-notes/0.0.1-beta.147/content.md +10 -0
  130. package/docs/resources/release-notes/0.0.1-beta.149/content.md +10 -0
  131. package/docs/resources/release-notes/0.0.1-beta.150/content.md +13 -0
  132. package/docs/resources/release-notes/0.0.1-beta.152/content.md +7 -0
  133. package/docs/resources/release-notes/0.0.1-beta.154/content.md +15 -0
  134. package/docs/resources/release-notes/0.0.1-beta.156/content.md +7 -0
  135. package/docs/resources/release-notes/0.0.1-beta.158/content.md +9 -0
  136. package/docs/resources/release-notes/0.0.1-beta.159/content.md +11 -0
  137. package/docs/resources/release-notes/0.0.1-beta.160/content.md +7 -0
  138. package/docs/resources/release-notes/0.0.1-beta.161/content.md +7 -0
  139. package/docs/resources/release-notes/0.0.1-beta.163/content.md +7 -0
  140. package/docs/resources/release-notes/0.0.1-beta.164/content.md +9 -0
  141. package/docs/resources/release-notes/0.0.1-beta.166/content.md +17 -0
  142. package/docs/resources/release-notes/0.0.1-beta.167/content.md +7 -0
  143. package/docs/resources/release-notes/0.0.1-beta.168/content.md +7 -0
  144. package/docs/resources/release-notes/0.0.1-beta.169/content.md +7 -0
  145. package/docs/resources/release-notes/0.0.1-beta.171/content.md +16 -0
  146. package/docs/resources/release-notes/0.0.1-beta.172/content.md +24 -0
  147. package/docs/resources/release-notes/0.0.1-beta.173/content.md +15 -0
  148. package/docs/resources/release-notes/0.0.1-beta.174/content.md +7 -0
  149. package/docs/resources/release-notes/0.0.1-beta.176/content.md +32 -0
  150. package/docs/resources/release-notes/0.0.1-beta.179/content.md +11 -0
  151. package/docs/resources/release-notes/0.0.1-beta.182/content.md +13 -0
  152. package/docs/resources/release-notes/0.0.1-beta.185/content.md +7 -0
  153. package/docs/resources/release-notes/0.0.1-beta.187/content.md +27 -0
  154. package/docs/resources/release-notes/0.1.1/content.md +23 -0
  155. package/docs/resources/release-notes/0.1.2/content.md +7 -0
  156. package/docs/resources/release-notes/0.1.4/content.md +19 -0
  157. package/docs/resources/release-notes/0.1.5/content.md +7 -0
  158. package/docs/resources/release-notes/0.1.6/content.md +7 -0
  159. package/docs/resources/release-notes/0.2.0/content.md +31 -0
  160. package/docs/resources/release-notes/0.2.1/content.md +17 -0
  161. package/docs/resources/release-notes/0.2.2/content.md +11 -0
  162. package/docs/resources/release-notes/0.2.3/content.md +15 -0
  163. package/docs/resources/release-notes/content.md +64 -0
  164. package/lib/commonjs/components/DateTimeList/index.js +11 -26
  165. package/lib/commonjs/components/DateTimeList/index.js.map +1 -1
  166. package/lib/commonjs/components/DateTimeList/styles.js +2 -12
  167. package/lib/commonjs/components/DateTimeList/styles.js.map +1 -1
  168. package/lib/commonjs/components/ListItem/index.js.map +1 -1
  169. package/lib/commonjs/components/ListItem/styles.js +2 -1
  170. package/lib/commonjs/components/ListItem/styles.js.map +1 -1
  171. package/lib/commonjs/components/Menu/index.js +11 -5
  172. package/lib/commonjs/components/Menu/index.js.map +1 -1
  173. package/lib/commonjs/components/ScrollShadow/gradient.js +29 -0
  174. package/lib/commonjs/components/ScrollShadow/gradient.js.map +1 -0
  175. package/lib/commonjs/components/ScrollShadow/index.js +171 -44
  176. package/lib/commonjs/components/ScrollShadow/index.js.map +1 -1
  177. package/lib/commonjs/components/ScrollShadow/styles.js +58 -14
  178. package/lib/commonjs/components/ScrollShadow/styles.js.map +1 -1
  179. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js +63 -0
  180. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  181. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +48 -8
  182. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
  183. package/lib/commonjs/components/Tabs/index.js +16 -23
  184. package/lib/commonjs/components/Tabs/index.js.map +1 -1
  185. package/lib/commonjs/components/Tabs/styles.js +1 -10
  186. package/lib/commonjs/components/Tabs/styles.js.map +1 -1
  187. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js +20 -5
  188. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js.map +1 -1
  189. package/lib/module/components/DateTimeList/index.js +12 -27
  190. package/lib/module/components/DateTimeList/index.js.map +1 -1
  191. package/lib/module/components/DateTimeList/styles.js +1 -11
  192. package/lib/module/components/DateTimeList/styles.js.map +1 -1
  193. package/lib/module/components/ListItem/index.js.map +1 -1
  194. package/lib/module/components/ListItem/styles.js +2 -1
  195. package/lib/module/components/ListItem/styles.js.map +1 -1
  196. package/lib/module/components/Menu/index.js +11 -5
  197. package/lib/module/components/Menu/index.js.map +1 -1
  198. package/lib/module/components/ScrollShadow/gradient.js +24 -0
  199. package/lib/module/components/ScrollShadow/gradient.js.map +1 -0
  200. package/lib/module/components/ScrollShadow/index.js +170 -48
  201. package/lib/module/components/ScrollShadow/index.js.map +1 -1
  202. package/lib/module/components/ScrollShadow/styles.js +57 -13
  203. package/lib/module/components/ScrollShadow/styles.js.map +1 -1
  204. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js +57 -0
  205. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  206. package/lib/module/components/ScrollShadow/useScrollShadow.js +46 -8
  207. package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
  208. package/lib/module/components/Tabs/index.js +17 -24
  209. package/lib/module/components/Tabs/index.js.map +1 -1
  210. package/lib/module/components/Tabs/styles.js +0 -9
  211. package/lib/module/components/Tabs/styles.js.map +1 -1
  212. package/lib/module/figma/ListItem.SectionHeader.figma.js +20 -5
  213. package/lib/module/figma/ListItem.SectionHeader.figma.js.map +1 -1
  214. package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -1
  215. package/lib/typescript/components/DateTimeList/styles.d.ts +1 -4
  216. package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -1
  217. package/lib/typescript/components/ListItem/index.d.ts +5 -4
  218. package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
  219. package/lib/typescript/components/ListItem/styles.d.ts +1 -1
  220. package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
  221. package/lib/typescript/components/Menu/index.d.ts.map +1 -1
  222. package/lib/typescript/components/ScrollShadow/gradient.d.ts +7 -0
  223. package/lib/typescript/components/ScrollShadow/gradient.d.ts.map +1 -0
  224. package/lib/typescript/components/ScrollShadow/index.d.ts +57 -15
  225. package/lib/typescript/components/ScrollShadow/index.d.ts.map +1 -1
  226. package/lib/typescript/components/ScrollShadow/styles.d.ts +8 -2
  227. package/lib/typescript/components/ScrollShadow/styles.d.ts.map +1 -1
  228. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts +13 -0
  229. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts.map +1 -0
  230. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts +15 -2
  231. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
  232. package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
  233. package/lib/typescript/components/Tabs/styles.d.ts +0 -7
  234. package/lib/typescript/components/Tabs/styles.d.ts.map +1 -1
  235. package/lib/typescript/figma/ListItem.SectionHeader.figma.d.ts.map +1 -1
  236. package/package.json +8 -6
  237. package/src/components/DateTimeList/index.tsx +13 -26
  238. package/src/components/DateTimeList/styles.ts +1 -10
  239. package/src/components/ListItem/index.tsx +5 -4
  240. package/src/components/ListItem/styles.ts +1 -0
  241. package/src/components/Menu/index.tsx +11 -8
  242. package/src/components/ScrollShadow/gradient.ts +48 -0
  243. package/src/components/ScrollShadow/index.tsx +300 -69
  244. package/src/components/ScrollShadow/styles.ts +45 -28
  245. package/src/components/ScrollShadow/useComposedScrollHandler.ts +58 -0
  246. package/src/components/ScrollShadow/useScrollShadow.ts +72 -10
  247. package/src/components/Tabs/index.tsx +25 -35
  248. package/src/components/Tabs/styles.ts +0 -9
@@ -1,4 +1,5 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { Platform } from 'react-native';
2
3
  import type { LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
3
4
 
4
5
  export interface ScrollShadowCapability {
@@ -9,9 +10,26 @@ export interface ScrollShadowCapability {
9
10
  export interface UseScrollShadowOptions {
10
11
  orientation?: 'horizontal' | 'vertical';
11
12
  offset?: number;
13
+ enabled?: boolean;
12
14
  onCapabilityChange?: (capability: ScrollShadowCapability) => void;
13
15
  }
14
16
 
17
+ export interface UseScrollShadowReturn {
18
+ capability: ScrollShadowCapability;
19
+ handleLayout: (event: LayoutChangeEvent) => void;
20
+ handleContentSizeChange: (width: number, height: number) => void;
21
+ handleScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
22
+ }
23
+
24
+ export interface ScrollShadowDistance {
25
+ before: number;
26
+ after: number;
27
+ }
28
+
29
+ interface ScrollShadowTrackerOptions extends UseScrollShadowOptions {
30
+ onDistanceChange?: (distance: ScrollShadowDistance) => void;
31
+ }
32
+
15
33
  interface ScrollMetrics {
16
34
  scrollOffset: number;
17
35
  viewportSize: number;
@@ -24,6 +42,20 @@ const INITIAL_METRICS: ScrollMetrics = {
24
42
  contentSize: 0,
25
43
  };
26
44
 
45
+ export function normalizeAxisScrollOffset(
46
+ rawOffset: number,
47
+ orientation: 'horizontal' | 'vertical',
48
+ maxOffset: number,
49
+ platform: typeof Platform.OS = Platform.OS,
50
+ ): number {
51
+ // Web RTL reports a negative x and browsers do not rubber-band it. Native RTL
52
+ // stays positive, so a negative native offset is overscroll at the start edge.
53
+ const offset =
54
+ orientation === 'horizontal' && platform === 'web' ? Math.abs(rawOffset) : rawOffset;
55
+
56
+ return Math.min(Math.max(0, offset), Math.max(0, maxOffset));
57
+ }
58
+
27
59
  function getScrollCapability(metrics: ScrollMetrics, offset: number): ScrollShadowCapability {
28
60
  const { scrollOffset, viewportSize, contentSize } = metrics;
29
61
 
@@ -37,18 +69,42 @@ function getScrollCapability(metrics: ScrollMetrics, offset: number): ScrollShad
37
69
  };
38
70
  }
39
71
 
40
- export function useScrollShadow({
41
- orientation = 'horizontal',
72
+ function getScrollDistance(metrics: ScrollMetrics, offset: number): ScrollShadowDistance {
73
+ const { scrollOffset, viewportSize, contentSize } = metrics;
74
+
75
+ if (viewportSize <= 0 || contentSize <= viewportSize) {
76
+ return { before: 0, after: 0 };
77
+ }
78
+
79
+ return {
80
+ before: Math.max(0, scrollOffset - offset),
81
+ after: Math.max(0, contentSize - viewportSize - scrollOffset - offset),
82
+ };
83
+ }
84
+
85
+ export function useScrollShadow(options: UseScrollShadowOptions = {}): UseScrollShadowReturn {
86
+ return useScrollShadowTracker(options);
87
+ }
88
+
89
+ export function useScrollShadowTracker({
90
+ orientation = 'vertical',
42
91
  offset = 0,
92
+ enabled = true,
43
93
  onCapabilityChange,
44
- }: UseScrollShadowOptions = {}) {
45
- const metricsRef = useRef<ScrollMetrics>(INITIAL_METRICS);
94
+ onDistanceChange,
95
+ }: ScrollShadowTrackerOptions = {}): UseScrollShadowReturn {
96
+ const metricsRef = useRef<ScrollMetrics>({ ...INITIAL_METRICS });
46
97
  const [capability, setCapability] = useState<ScrollShadowCapability>({
47
98
  canScrollBefore: false,
48
99
  canScrollAfter: false,
49
100
  });
50
101
 
51
102
  const updateCapability = useCallback(() => {
103
+ if (!enabled) {
104
+ return;
105
+ }
106
+
107
+ onDistanceChange?.(getScrollDistance(metricsRef.current, offset));
52
108
  const nextCapability = getScrollCapability(metricsRef.current, offset);
53
109
 
54
110
  setCapability((prev) => {
@@ -62,7 +118,7 @@ export function useScrollShadow({
62
118
  onCapabilityChange?.(nextCapability);
63
119
  return nextCapability;
64
120
  });
65
- }, [offset, onCapabilityChange]);
121
+ }, [enabled, offset, onCapabilityChange, onDistanceChange]);
66
122
 
67
123
  useEffect(() => {
68
124
  updateCapability();
@@ -88,13 +144,19 @@ export function useScrollShadow({
88
144
  const handleScroll = useCallback(
89
145
  (event: NativeSyntheticEvent<NativeScrollEvent>) => {
90
146
  const { contentOffset, layoutMeasurement, contentSize } = event.nativeEvent;
147
+ const rawOffset = orientation === 'vertical' ? contentOffset.y : contentOffset.x;
91
148
 
92
- metricsRef.current.scrollOffset =
93
- orientation === 'vertical' ? contentOffset.y : contentOffset.x;
94
- metricsRef.current.viewportSize =
149
+ const viewportSize =
95
150
  orientation === 'vertical' ? layoutMeasurement.height : layoutMeasurement.width;
96
- metricsRef.current.contentSize =
97
- orientation === 'vertical' ? contentSize.height : contentSize.width;
151
+ const axisContentSize = orientation === 'vertical' ? contentSize.height : contentSize.width;
152
+
153
+ metricsRef.current.scrollOffset = normalizeAxisScrollOffset(
154
+ rawOffset,
155
+ orientation,
156
+ axisContentSize - viewportSize,
157
+ );
158
+ metricsRef.current.viewportSize = viewportSize;
159
+ metricsRef.current.contentSize = axisContentSize;
98
160
 
99
161
  updateCapability();
100
162
  },
@@ -58,8 +58,6 @@ import {
58
58
  tabsTabLabelVariants,
59
59
  tabsTabVariants,
60
60
  TABS_INDICATOR_TRANSITION_MS,
61
- TABS_SOLID_SCROLL_FADE_SIZE,
62
- TABS_SCROLL_FADE_SIZE,
63
61
  OUTLINE_INDICATOR_THICKNESS,
64
62
  type TabsVariant,
65
63
  } from './styles';
@@ -178,7 +176,6 @@ const TabsList = forwardRef<ComponentRef<typeof View>, TabsListProps>(
178
176
  const { value, orientation, getTabs } = useTabsContext();
179
177
  const { variant } = useTabsVariantContext();
180
178
  const isHorizontalScroll = orientation === 'horizontal' && scrollable;
181
- const isWebHorizontalScroll = isHorizontalScroll && Platform.OS === 'web';
182
179
  const shouldAutoScrollActiveTab = isHorizontalScroll && Platform.OS !== 'web';
183
180
 
184
181
  const layoutsRef = useRef<Map<string, TabLayout>>(new Map());
@@ -478,23 +475,26 @@ const TabsList = forwardRef<ComponentRef<typeof View>, TabsListProps>(
478
475
  );
479
476
  };
480
477
 
481
- const solidWebHorizontalScroll = (
478
+ const horizontalScroll = (
479
+ <ScrollShadow
480
+ hideScrollBar={Platform.OS === 'web'}
481
+ orientation="horizontal"
482
+ surface={isSolidHorizontalScroll ? 'secondary' : 'background'}
483
+ size={isSolidHorizontalScroll ? 'default' : 'small'}
484
+ edgeClassName={isSolidHorizontalScroll ? undefined : 'opacity-85'}
485
+ onCapabilityChange={setScrollCapability}
486
+ >
487
+ {horizontalScrollView}
488
+ </ScrollShadow>
489
+ );
490
+
491
+ const webHorizontalScroll = isSolidHorizontalScroll ? (
482
492
  <View className="relative min-w-0 w-full">
483
- <ScrollShadow
484
- hideScrollBar
485
- orientation="horizontal"
486
- size={TABS_SOLID_SCROLL_FADE_SIZE}
487
- fadeFromClassName="from-surface-secondary"
488
- onCapabilityChange={setScrollCapability}
489
- >
490
- {horizontalScrollView}
491
- </ScrollShadow>
493
+ {horizontalScroll}
492
494
  {renderSolidScrollChevron('start', -1)}
493
495
  {renderSolidScrollChevron('end', 1)}
494
496
  </View>
495
- );
496
-
497
- const outlineWebHorizontalScroll = (
497
+ ) : (
498
498
  <View className="w-full min-w-0 flex-row items-stretch">
499
499
  {scrollCapability.canScrollBefore ? (
500
500
  <Pressable
@@ -507,17 +507,7 @@ const TabsList = forwardRef<ComponentRef<typeof View>, TabsListProps>(
507
507
  <Icon as={ChevronLeft} className="size-4 text-content-secondary" />
508
508
  </Pressable>
509
509
  ) : null}
510
- <View className="min-w-0 flex-1">
511
- <ScrollShadow
512
- hideScrollBar
513
- orientation="horizontal"
514
- size={TABS_SCROLL_FADE_SIZE}
515
- fadeFromClassName="from-background/85"
516
- onCapabilityChange={setScrollCapability}
517
- >
518
- {horizontalScrollView}
519
- </ScrollShadow>
520
- </View>
510
+ <View className="min-w-0 flex-1">{horizontalScroll}</View>
521
511
  {scrollCapability.canScrollAfter ? (
522
512
  <Pressable
523
513
  accessibilityLabel="Scroll tabs right"
@@ -542,14 +532,14 @@ const TabsList = forwardRef<ComponentRef<typeof View>, TabsListProps>(
542
532
  {...props}
543
533
  {...mergeDataAttributes(props, dataAttributes({ slot: 'tabs-list' }))}
544
534
  >
545
- {isWebHorizontalScroll ? (
546
- <View className={cn(tabsListScrollContainerVariants())}>
547
- {wrapSolidScrollShell(
548
- isSolidHorizontalScroll ? solidWebHorizontalScroll : outlineWebHorizontalScroll,
549
- )}
550
- </View>
551
- ) : isHorizontalScroll ? (
552
- wrapSolidScrollShell(horizontalScrollView)
535
+ {isHorizontalScroll ? (
536
+ Platform.OS === 'web' ? (
537
+ <View className={cn(tabsListScrollContainerVariants())}>
538
+ {wrapSolidScrollShell(webHorizontalScroll)}
539
+ </View>
540
+ ) : (
541
+ wrapSolidScrollShell(horizontalScroll)
542
+ )
553
543
  ) : (
554
544
  listTrack
555
545
  )}
@@ -37,15 +37,6 @@ export const OUTLINE_INDICATOR_THICKNESS = 2;
37
37
  */
38
38
  export const TABS_INDICATOR_TRANSITION_MS = 150;
39
39
 
40
- /** Outline horizontal scroll — narrow fade reads cleanly against the page background. */
41
- export const TABS_SCROLL_FADE_SIZE = 32;
42
-
43
- /**
44
- * Solid horizontal scroll — wider fade so tabs dissolve smoothly into the track (and under the
45
- * overlay chevron) instead of ending in a hard clip at the scroll viewport edge.
46
- */
47
- export const TABS_SOLID_SCROLL_FADE_SIZE = 40;
48
-
49
40
  /**
50
41
  * Room reserved on the left/right sides inside the horizontal-scroll clip rect for ink that
51
42
  * paints past a tab's own box: `shadow-sm` (`0px 1px 3px`, solid only) and the web focus ring