@webority-technologies/mobile 0.0.14 → 0.0.20

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 (202) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +60 -19
  2. package/lib/commonjs/components/AppBar/AppBar.js +29 -20
  3. package/lib/commonjs/components/Avatar/Avatar.js +38 -8
  4. package/lib/commonjs/components/Badge/Badge.js +66 -4
  5. package/lib/commonjs/components/Banner/Banner.js +146 -66
  6. package/lib/commonjs/components/BottomNavigation/BottomNavigation.js +37 -15
  7. package/lib/commonjs/components/BottomSheet/BottomSheet.js +85 -50
  8. package/lib/commonjs/components/Button/Button.js +12 -5
  9. package/lib/commonjs/components/Card/Card.js +106 -16
  10. package/lib/commonjs/components/Carousel/Carousel.js +66 -12
  11. package/lib/commonjs/components/Checkbox/Checkbox.js +11 -7
  12. package/lib/commonjs/components/Chip/Chip.js +44 -12
  13. package/lib/commonjs/components/DatePicker/DatePicker.js +185 -76
  14. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +133 -59
  15. package/lib/commonjs/components/Dialog/Dialog.js +16 -10
  16. package/lib/commonjs/components/Drawer/Drawer.js +13 -10
  17. package/lib/commonjs/components/FieldBase/FieldBase.js +306 -0
  18. package/lib/commonjs/components/FieldBase/index.js +32 -0
  19. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +69 -44
  20. package/lib/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
  21. package/lib/commonjs/components/FormField/FormField.js +3 -2
  22. package/lib/commonjs/components/ImageGallery/ImageGallery.js +132 -44
  23. package/lib/commonjs/components/Input/Input.js +144 -181
  24. package/lib/commonjs/components/ListItem/ListItem.js +90 -11
  25. package/lib/commonjs/components/Modal/Modal.js +55 -27
  26. package/lib/commonjs/components/NumberInput/NumberInput.js +60 -106
  27. package/lib/commonjs/components/OTPInput/OTPInput.js +65 -58
  28. package/lib/commonjs/components/PickerTrigger/PickerTrigger.js +185 -0
  29. package/lib/commonjs/components/{AppIcon → PickerTrigger}/index.js +4 -4
  30. package/lib/commonjs/components/ProgressBar/ProgressBar.js +19 -11
  31. package/lib/commonjs/components/Radio/Radio.js +11 -6
  32. package/lib/commonjs/components/Rating/Rating.js +85 -19
  33. package/lib/commonjs/components/SearchBar/SearchBar.js +84 -107
  34. package/lib/commonjs/components/SegmentedControl/SegmentedControl.js +22 -11
  35. package/lib/commonjs/components/Select/Select.js +62 -91
  36. package/lib/commonjs/components/Skeleton/Skeleton.js +131 -174
  37. package/lib/commonjs/components/Skeleton/SkeletonClock.js +117 -0
  38. package/lib/commonjs/components/Skeleton/SkeletonContent.js +164 -81
  39. package/lib/commonjs/components/Skeleton/SkeletonProvider.js +72 -10
  40. package/lib/commonjs/components/Skeleton/index.js +17 -16
  41. package/lib/commonjs/components/Slider/Slider.js +44 -25
  42. package/lib/commonjs/components/Stepper/Stepper.js +199 -29
  43. package/lib/commonjs/components/Swipeable/Swipeable.js +36 -19
  44. package/lib/commonjs/components/Switch/Switch.js +9 -2
  45. package/lib/commonjs/components/Tabs/Tabs.js +84 -21
  46. package/lib/commonjs/components/TimePicker/TimePicker.js +123 -45
  47. package/lib/commonjs/components/Toast/Toast.js +27 -16
  48. package/lib/commonjs/components/Tooltip/Tooltip.js +56 -32
  49. package/lib/commonjs/components/index.js +37 -37
  50. package/lib/commonjs/theme/tokens.js +55 -7
  51. package/lib/module/components/Accordion/Accordion.js +61 -20
  52. package/lib/module/components/AppBar/AppBar.js +29 -20
  53. package/lib/module/components/Avatar/Avatar.js +39 -9
  54. package/lib/module/components/Badge/Badge.js +67 -5
  55. package/lib/module/components/Banner/Banner.js +147 -67
  56. package/lib/module/components/BottomNavigation/BottomNavigation.js +37 -15
  57. package/lib/module/components/BottomSheet/BottomSheet.js +87 -52
  58. package/lib/module/components/Button/Button.js +12 -5
  59. package/lib/module/components/Card/Card.js +107 -17
  60. package/lib/module/components/Carousel/Carousel.js +67 -13
  61. package/lib/module/components/Checkbox/Checkbox.js +11 -7
  62. package/lib/module/components/Chip/Chip.js +45 -13
  63. package/lib/module/components/DatePicker/DatePicker.js +185 -76
  64. package/lib/module/components/DateRangePicker/DateRangePicker.js +134 -60
  65. package/lib/module/components/Dialog/Dialog.js +16 -10
  66. package/lib/module/components/Drawer/Drawer.js +13 -10
  67. package/lib/module/components/FieldBase/FieldBase.js +297 -0
  68. package/lib/module/components/FieldBase/index.js +4 -0
  69. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +69 -44
  70. package/lib/module/components/ForceUpdateDialog/ForceUpdateDialog.js +8 -2
  71. package/lib/module/components/FormField/FormField.js +3 -2
  72. package/lib/module/components/ImageGallery/ImageGallery.js +128 -40
  73. package/lib/module/components/Input/Input.js +144 -179
  74. package/lib/module/components/ListItem/ListItem.js +91 -12
  75. package/lib/module/components/Modal/Modal.js +55 -27
  76. package/lib/module/components/NumberInput/NumberInput.js +60 -106
  77. package/lib/module/components/OTPInput/OTPInput.js +65 -58
  78. package/lib/module/components/PickerTrigger/PickerTrigger.js +181 -0
  79. package/lib/module/components/PickerTrigger/index.js +4 -0
  80. package/lib/module/components/ProgressBar/ProgressBar.js +19 -11
  81. package/lib/module/components/Radio/Radio.js +11 -6
  82. package/lib/module/components/Rating/Rating.js +86 -20
  83. package/lib/module/components/SearchBar/SearchBar.js +84 -107
  84. package/lib/module/components/SegmentedControl/SegmentedControl.js +22 -11
  85. package/lib/module/components/Select/Select.js +62 -91
  86. package/lib/module/components/Skeleton/Skeleton.js +135 -175
  87. package/lib/module/components/Skeleton/SkeletonClock.js +110 -0
  88. package/lib/module/components/Skeleton/SkeletonContent.js +167 -84
  89. package/lib/module/components/Skeleton/SkeletonProvider.js +71 -10
  90. package/lib/module/components/Skeleton/index.js +3 -2
  91. package/lib/module/components/Slider/Slider.js +44 -25
  92. package/lib/module/components/Stepper/Stepper.js +201 -31
  93. package/lib/module/components/Swipeable/Swipeable.js +36 -19
  94. package/lib/module/components/Switch/Switch.js +9 -2
  95. package/lib/module/components/Tabs/Tabs.js +84 -21
  96. package/lib/module/components/TimePicker/TimePicker.js +123 -45
  97. package/lib/module/components/Toast/Toast.js +27 -16
  98. package/lib/module/components/Tooltip/Tooltip.js +56 -32
  99. package/lib/module/components/index.js +2 -2
  100. package/lib/module/theme/tokens.js +55 -7
  101. package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +10 -5
  102. package/lib/typescript/commonjs/components/AppBar/AppBar.d.ts +8 -0
  103. package/lib/typescript/commonjs/components/Avatar/Avatar.d.ts +12 -6
  104. package/lib/typescript/commonjs/components/Badge/Badge.d.ts +7 -6
  105. package/lib/typescript/commonjs/components/Banner/Banner.d.ts +17 -6
  106. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +7 -0
  107. package/lib/typescript/commonjs/components/Card/Card.d.ts +17 -6
  108. package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +7 -6
  109. package/lib/typescript/commonjs/components/Checkbox/Checkbox.d.ts +9 -1
  110. package/lib/typescript/commonjs/components/Chip/Chip.d.ts +13 -6
  111. package/lib/typescript/commonjs/components/DatePicker/DatePicker.d.ts +38 -3
  112. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +36 -3
  113. package/lib/typescript/commonjs/components/Dialog/Dialog.d.ts +13 -1
  114. package/lib/typescript/commonjs/components/FieldBase/FieldBase.d.ts +141 -0
  115. package/lib/typescript/commonjs/components/FieldBase/index.d.ts +3 -0
  116. package/lib/typescript/commonjs/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
  117. package/lib/typescript/commonjs/components/FloatingActionButton/index.d.ts +1 -1
  118. package/lib/typescript/commonjs/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
  119. package/lib/typescript/commonjs/components/FormField/FormField.d.ts +7 -0
  120. package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -4
  121. package/lib/typescript/commonjs/components/Input/Input.d.ts +6 -0
  122. package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +13 -6
  123. package/lib/typescript/commonjs/components/NumberInput/NumberInput.d.ts +3 -0
  124. package/lib/typescript/commonjs/components/PickerTrigger/PickerTrigger.d.ts +57 -0
  125. package/lib/typescript/commonjs/components/PickerTrigger/index.d.ts +3 -0
  126. package/lib/typescript/commonjs/components/ProgressBar/ProgressBar.d.ts +2 -0
  127. package/lib/typescript/commonjs/components/Radio/Radio.d.ts +3 -0
  128. package/lib/typescript/commonjs/components/Rating/Rating.d.ts +9 -6
  129. package/lib/typescript/commonjs/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  130. package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +49 -20
  131. package/lib/typescript/commonjs/components/Skeleton/SkeletonClock.d.ts +60 -0
  132. package/lib/typescript/commonjs/components/Skeleton/SkeletonContent.d.ts +80 -19
  133. package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +39 -5
  134. package/lib/typescript/commonjs/components/Skeleton/index.d.ts +6 -4
  135. package/lib/typescript/commonjs/components/Slider/Slider.d.ts +12 -1
  136. package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +18 -6
  137. package/lib/typescript/commonjs/components/Swipeable/Swipeable.d.ts +2 -0
  138. package/lib/typescript/commonjs/components/Switch/Switch.d.ts +1 -0
  139. package/lib/typescript/commonjs/components/Tabs/Tabs.d.ts +26 -2
  140. package/lib/typescript/commonjs/components/TimePicker/TimePicker.d.ts +36 -3
  141. package/lib/typescript/commonjs/components/Toast/Toast.d.ts +8 -0
  142. package/lib/typescript/commonjs/components/Tooltip/Tooltip.d.ts +7 -1
  143. package/lib/typescript/commonjs/components/index.d.ts +5 -5
  144. package/lib/typescript/commonjs/index.d.ts +1 -1
  145. package/lib/typescript/commonjs/theme/index.d.ts +1 -1
  146. package/lib/typescript/commonjs/theme/types.d.ts +553 -11
  147. package/lib/typescript/module/components/Accordion/Accordion.d.ts +10 -5
  148. package/lib/typescript/module/components/AppBar/AppBar.d.ts +8 -0
  149. package/lib/typescript/module/components/Avatar/Avatar.d.ts +12 -6
  150. package/lib/typescript/module/components/Badge/Badge.d.ts +7 -6
  151. package/lib/typescript/module/components/Banner/Banner.d.ts +17 -6
  152. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +7 -0
  153. package/lib/typescript/module/components/Card/Card.d.ts +17 -6
  154. package/lib/typescript/module/components/Carousel/Carousel.d.ts +7 -6
  155. package/lib/typescript/module/components/Checkbox/Checkbox.d.ts +9 -1
  156. package/lib/typescript/module/components/Chip/Chip.d.ts +13 -6
  157. package/lib/typescript/module/components/DatePicker/DatePicker.d.ts +38 -3
  158. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +36 -3
  159. package/lib/typescript/module/components/Dialog/Dialog.d.ts +13 -1
  160. package/lib/typescript/module/components/FieldBase/FieldBase.d.ts +141 -0
  161. package/lib/typescript/module/components/FieldBase/index.d.ts +3 -0
  162. package/lib/typescript/module/components/FloatingActionButton/FloatingActionButton.d.ts +8 -6
  163. package/lib/typescript/module/components/FloatingActionButton/index.d.ts +1 -1
  164. package/lib/typescript/module/components/ForceUpdateDialog/ForceUpdateDialog.d.ts +7 -0
  165. package/lib/typescript/module/components/FormField/FormField.d.ts +7 -0
  166. package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -4
  167. package/lib/typescript/module/components/Input/Input.d.ts +6 -0
  168. package/lib/typescript/module/components/ListItem/ListItem.d.ts +13 -6
  169. package/lib/typescript/module/components/NumberInput/NumberInput.d.ts +3 -0
  170. package/lib/typescript/module/components/PickerTrigger/PickerTrigger.d.ts +57 -0
  171. package/lib/typescript/module/components/PickerTrigger/index.d.ts +3 -0
  172. package/lib/typescript/module/components/ProgressBar/ProgressBar.d.ts +2 -0
  173. package/lib/typescript/module/components/Radio/Radio.d.ts +3 -0
  174. package/lib/typescript/module/components/Rating/Rating.d.ts +9 -6
  175. package/lib/typescript/module/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  176. package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +49 -20
  177. package/lib/typescript/module/components/Skeleton/SkeletonClock.d.ts +60 -0
  178. package/lib/typescript/module/components/Skeleton/SkeletonContent.d.ts +80 -19
  179. package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +39 -5
  180. package/lib/typescript/module/components/Skeleton/index.d.ts +6 -4
  181. package/lib/typescript/module/components/Slider/Slider.d.ts +12 -1
  182. package/lib/typescript/module/components/Stepper/Stepper.d.ts +18 -6
  183. package/lib/typescript/module/components/Swipeable/Swipeable.d.ts +2 -0
  184. package/lib/typescript/module/components/Switch/Switch.d.ts +1 -0
  185. package/lib/typescript/module/components/Tabs/Tabs.d.ts +26 -2
  186. package/lib/typescript/module/components/TimePicker/TimePicker.d.ts +36 -3
  187. package/lib/typescript/module/components/Toast/Toast.d.ts +8 -0
  188. package/lib/typescript/module/components/Tooltip/Tooltip.d.ts +7 -1
  189. package/lib/typescript/module/components/index.d.ts +5 -5
  190. package/lib/typescript/module/index.d.ts +1 -1
  191. package/lib/typescript/module/theme/index.d.ts +1 -1
  192. package/lib/typescript/module/theme/types.d.ts +553 -11
  193. package/package.json +2 -6
  194. package/lib/commonjs/components/AppIcon/AppIcon.js +0 -120
  195. package/lib/commonjs/types/vector-icons.d.js +0 -2
  196. package/lib/module/components/AppIcon/AppIcon.js +0 -111
  197. package/lib/module/components/AppIcon/index.js +0 -4
  198. package/lib/module/types/vector-icons.d.js +0 -2
  199. package/lib/typescript/commonjs/components/AppIcon/AppIcon.d.ts +0 -20
  200. package/lib/typescript/commonjs/components/AppIcon/index.d.ts +0 -3
  201. package/lib/typescript/module/components/AppIcon/AppIcon.d.ts +0 -20
  202. package/lib/typescript/module/components/AppIcon/index.d.ts +0 -3
@@ -24,6 +24,11 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
24
24
  loading = false,
25
25
  accessibilityLabel,
26
26
  style,
27
+ containerStyle,
28
+ iconCircleStyle,
29
+ tintBarStyle,
30
+ closeButtonStyle,
31
+ actionButtonStyle,
27
32
  testID
28
33
  } = props;
29
34
  const theme = (0, _index.useTheme)();
@@ -77,7 +82,7 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
77
82
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
78
83
  style: [styles.iconCircle, {
79
84
  backgroundColor: tint.bar + '22'
80
- }],
85
+ }, iconCircleStyle],
81
86
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
82
87
  style: [styles.iconGlyph, {
83
88
  color: tint.glyphColor
@@ -104,11 +109,11 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
104
109
  transform: [{
105
110
  translateY
106
111
  }]
107
- }, style],
112
+ }, style, containerStyle],
108
113
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
109
114
  style: [styles.tintBar, {
110
115
  backgroundColor: tint.bar
111
- }]
116
+ }, tintBarStyle]
112
117
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
113
118
  style: styles.row,
114
119
  children: [renderIcon(), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
@@ -145,11 +150,11 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
145
150
  pressed
146
151
  }) => [styles.closeBtn, {
147
152
  backgroundColor: pressed ? theme.colors.surface.pressed : 'transparent'
148
- }],
153
+ }, closeButtonStyle],
149
154
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
150
155
  style: {
151
156
  color: theme.colors.text.secondary,
152
- fontSize: 18,
157
+ fontSize: theme.components.banner?.closeGlyphFontSize ?? 18,
153
158
  fontWeight: theme.typography.fontWeight.bold,
154
159
  lineHeight: 18
155
160
  },
@@ -169,7 +174,7 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
169
174
  pressed
170
175
  }) => [styles.actionBtn, {
171
176
  backgroundColor: pressed ? theme.colors.surface.pressed : 'transparent'
172
- }],
177
+ }, actionButtonStyle],
173
178
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
174
179
  style: {
175
180
  color: isPrimary ? tint.glyphColor : theme.colors.text.secondary,
@@ -184,15 +189,86 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
184
189
  }) : null]
185
190
  });
186
191
  if (loading) {
187
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.SkeletonContent, {
188
- loading: true,
189
- mode: "auto",
190
- children: rendered
192
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(BannerSkeleton, {
193
+ ...props
191
194
  });
192
195
  }
193
196
  return rendered;
194
197
  });
195
198
  Banner.displayName = 'Banner';
199
+
200
+ /**
201
+ * Placeholder shape for `<Banner>`. Keeps the icon circle on the left and
202
+ * shows title + 1-2 message lines + optional action button row. Outer
203
+ * container retains the elevated background so the banner footprint
204
+ * doesn't shift when it loads.
205
+ */
206
+ const BannerSkeleton = ({
207
+ title,
208
+ actions,
209
+ icon,
210
+ containerStyle,
211
+ style
212
+ }) => {
213
+ const theme = (0, _index.useTheme)();
214
+ const showIcon = icon !== false;
215
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
216
+ style: [{
217
+ flexDirection: 'row',
218
+ alignItems: 'flex-start',
219
+ backgroundColor: theme.colors.background.elevated,
220
+ borderRadius: theme.radius.md,
221
+ padding: theme.spacing.md,
222
+ borderWidth: 1,
223
+ borderColor: theme.colors.border.primary
224
+ }, containerStyle, style],
225
+ accessibilityRole: "progressbar",
226
+ accessibilityState: {
227
+ busy: true
228
+ },
229
+ children: [showIcon ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
230
+ style: {
231
+ marginRight: theme.spacing.sm
232
+ },
233
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Skeleton, {
234
+ shape: "circle",
235
+ width: 32,
236
+ height: 32
237
+ })
238
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
239
+ style: {
240
+ flex: 1
241
+ },
242
+ children: [title !== undefined ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Skeleton, {
243
+ shape: "text",
244
+ width: "55%",
245
+ height: 16,
246
+ style: {
247
+ marginBottom: theme.spacing.xs
248
+ }
249
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.SkeletonText, {
250
+ lines: 2,
251
+ fontSize: 13,
252
+ lastLineWidth: "70%"
253
+ }), actions && actions.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
254
+ style: {
255
+ flexDirection: 'row',
256
+ marginTop: theme.spacing.sm
257
+ },
258
+ children: actions.map((_, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Skeleton, {
259
+ width: 72,
260
+ height: 28,
261
+ shape: "rounded",
262
+ style: {
263
+ marginRight: theme.spacing.sm
264
+ }
265
+ }, `sk-banner-action-${i}`))
266
+ }) : null]
267
+ })]
268
+ });
269
+ };
270
+ BannerSkeleton.displayName = 'BannerSkeleton';
271
+ Banner.Skeleton = BannerSkeleton;
196
272
  const tintFor = (theme, variant) => {
197
273
  switch (variant) {
198
274
  case 'success':
@@ -228,61 +304,65 @@ const tintFor = (theme, variant) => {
228
304
  };
229
305
  }
230
306
  };
231
- const buildStyles = _theme => _reactNative.StyleSheet.create({
232
- container: {
233
- overflow: 'hidden',
234
- paddingLeft: 16
235
- },
236
- tintBar: {
237
- position: 'absolute',
238
- left: 0,
239
- top: 0,
240
- bottom: 0,
241
- width: 4
242
- },
243
- row: {
244
- flexDirection: 'row',
245
- alignItems: 'flex-start'
246
- },
247
- iconWrap: {
248
- marginRight: 12
249
- },
250
- iconCircle: {
251
- width: 28,
252
- height: 28,
253
- borderRadius: 14,
254
- alignItems: 'center',
255
- justifyContent: 'center',
256
- marginRight: 12
257
- },
258
- iconGlyph: {
259
- fontSize: 15,
260
- fontWeight: '700',
261
- lineHeight: 17
262
- },
263
- textBlock: {
264
- flex: 1,
265
- paddingRight: 8
266
- },
267
- closeBtn: {
268
- width: 28,
269
- height: 28,
270
- borderRadius: 14,
271
- alignItems: 'center',
272
- justifyContent: 'center',
273
- marginLeft: 4
274
- },
275
- actionsRow: {
276
- flexDirection: 'row',
277
- justifyContent: 'flex-end',
278
- marginTop: 8,
279
- gap: 4
280
- },
281
- actionBtn: {
282
- paddingHorizontal: 10,
283
- paddingVertical: 6,
284
- borderRadius: 8
285
- }
286
- });
307
+ const buildStyles = theme => {
308
+ const iconCircleSize = theme.components.banner?.iconCircleSize ?? 28;
309
+ const closeButtonSize = theme.components.banner?.closeButtonSize ?? 28;
310
+ return _reactNative.StyleSheet.create({
311
+ container: {
312
+ overflow: 'hidden',
313
+ paddingLeft: theme.components.banner?.containerPaddingLeft ?? theme.spacing.md
314
+ },
315
+ tintBar: {
316
+ position: 'absolute',
317
+ left: 0,
318
+ top: 0,
319
+ bottom: 0,
320
+ width: theme.components.banner?.tintBarWidth ?? 4
321
+ },
322
+ row: {
323
+ flexDirection: 'row',
324
+ alignItems: 'flex-start'
325
+ },
326
+ iconWrap: {
327
+ marginRight: theme.components.banner?.iconGap ?? theme.spacing.sm
328
+ },
329
+ iconCircle: {
330
+ width: iconCircleSize,
331
+ height: iconCircleSize,
332
+ borderRadius: theme.components.banner?.iconCircleRadius ?? iconCircleSize / 2,
333
+ alignItems: 'center',
334
+ justifyContent: 'center',
335
+ marginRight: theme.components.banner?.iconGap ?? theme.spacing.sm
336
+ },
337
+ iconGlyph: {
338
+ fontSize: theme.components.banner?.iconGlyphFontSize ?? 15,
339
+ fontWeight: '700',
340
+ lineHeight: theme.components.banner?.iconGlyphLineHeight ?? 17
341
+ },
342
+ textBlock: {
343
+ flex: 1,
344
+ paddingRight: theme.components.banner?.textBlockPaddingRight ?? theme.spacing.xs
345
+ },
346
+ closeBtn: {
347
+ width: closeButtonSize,
348
+ height: closeButtonSize,
349
+ borderRadius: theme.components.banner?.closeButtonRadius ?? closeButtonSize / 2,
350
+ alignItems: 'center',
351
+ justifyContent: 'center',
352
+ marginLeft: theme.components.banner?.closeButtonMarginLeft ?? theme.spacing.xxs ?? 4
353
+ },
354
+ actionsRow: {
355
+ flexDirection: 'row',
356
+ justifyContent: 'flex-end',
357
+ marginTop: theme.components.banner?.actionsRowMarginTop ?? theme.spacing.xs,
358
+ gap: theme.components.banner?.actionsRowGap ?? 4
359
+ },
360
+ actionBtn: {
361
+ paddingHorizontal: theme.components.banner?.actionButtonPaddingHorizontal ?? theme.spacing.sm,
362
+ paddingVertical: theme.components.banner?.actionButtonPaddingVertical ?? 6,
363
+ borderRadius: theme.components.banner?.actionButtonRadius ?? theme.radius.sm
364
+ }
365
+ });
366
+ };
287
367
  var _default = exports.default = Banner;
288
368
  //# sourceMappingURL=Banner.js.map
@@ -11,9 +11,11 @@ var _index = require("../../theme/index.js");
11
11
  var _index2 = require("../../utils/index.js");
12
12
  var _jsxRuntime = require("react/jsx-runtime");
13
13
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
- const ICON_SIZE = 24;
15
- const PILL_HEIGHT = 36;
16
- const UNDERLINE_HEIGHT = 3;
14
+ const DEFAULT_ICON_SIZE = 24;
15
+ const DEFAULT_PILL_HEIGHT = 36;
16
+ const DEFAULT_PILL_MAX_WIDTH = 120;
17
+ const DEFAULT_PILL_INSET = 16;
18
+ const DEFAULT_UNDERLINE_HEIGHT = 3;
17
19
  const formatBadge = value => {
18
20
  if (value === null || value === undefined || value === false) return null;
19
21
  if (value === true || value === '·') return {
@@ -62,8 +64,19 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
62
64
  const theme = (0, _index.useTheme)();
63
65
  const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
64
66
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
67
+ const tokens = theme.components.bottomNavigation;
68
+ const iconSize = tokens?.iconSize ?? DEFAULT_ICON_SIZE;
69
+ const pillHeight = tokens?.pillHeight ?? DEFAULT_PILL_HEIGHT;
70
+ const pillMaxWidth = tokens?.pillMaxWidth ?? DEFAULT_PILL_MAX_WIDTH;
71
+ const pillInset = tokens?.pillInset ?? DEFAULT_PILL_INSET;
65
72
  const activeIndex = Math.max(0, tabs.findIndex(tab => tab.key === activeTab));
66
73
  const [tabWidth, setTabWidth] = _react.default.useState(0);
74
+
75
+ // Single Animated.Value holds the pill's absolute pixel offset (active index
76
+ // × tab width + half the gap between tab edge and pill edge). Folding the
77
+ // offset into the same value avoids creating a fresh Animated.Value +
78
+ // Animated.add node on every render — earlier code did that and slowly
79
+ // leaked addition nodes as the user pressed tabs.
67
80
  const indicatorTranslateX = (0, _react.useRef)((0, _index.createAnimatedValue)(0)).current;
68
81
  const iconScales = (0, _react.useRef)({});
69
82
 
@@ -74,7 +87,17 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
74
87
  }
75
88
  });
76
89
 
77
- // Animate indicator when active tab changes or layout settles
90
+ // Pill width is intrinsic; we compute its rendered offset to keep it
91
+ // centered within each tab cell. The offset is applied to the pill itself
92
+ // (NOT folded into the shared indicatorTranslateX) so the underline indicator
93
+ // — which spans the full tab cell — stays aligned with the tab boundary
94
+ // instead of being shifted by the pill-centering math.
95
+ const pillWidth = tabWidth > 0 ? Math.min(tabWidth - pillInset, pillMaxWidth) : 0;
96
+ const pillOffset = tabWidth > 0 ? (tabWidth - pillWidth) / 2 : 0;
97
+
98
+ // Animate indicator to the active tab's cell edge. Pill mode applies the
99
+ // centering offset via a static `left` style below; underline mode uses
100
+ // this value directly.
78
101
  (0, _react.useEffect)(() => {
79
102
  if (tabWidth <= 0) return;
80
103
  _reactNative.Animated.spring(indicatorTranslateX, {
@@ -110,11 +133,6 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
110
133
  onTabPress(tab.key);
111
134
  };
112
135
  const paddingBottom = Math.max(8, insets.bottom);
113
-
114
- // Pill width is intrinsic; we compute its rendered offset to keep it centered
115
- // within each tab cell when it animates.
116
- const pillWidth = tabWidth > 0 ? Math.min(tabWidth - 16, 120) : 0;
117
- const pillOffset = tabWidth > 0 ? (tabWidth - pillWidth) / 2 : 0;
118
136
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
119
137
  ref: ref,
120
138
  testID: testID,
@@ -131,11 +149,12 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
131
149
  pointerEvents: "none",
132
150
  style: [styles.pill, {
133
151
  width: pillWidth,
134
- height: PILL_HEIGHT,
152
+ height: pillHeight,
153
+ left: pillOffset,
135
154
  backgroundColor: theme.colors.primaryMuted,
136
155
  borderRadius: theme.radius.full,
137
156
  transform: [{
138
- translateX: _reactNative.Animated.add(indicatorTranslateX, new _reactNative.Animated.Value(pillOffset))
157
+ translateX: indicatorTranslateX
139
158
  }]
140
159
  }, indicatorStyle]
141
160
  }) : null, tabs.map((tab, index) => {
@@ -167,13 +186,15 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
167
186
  testID: testID ? `${testID}-tab-${tab.key}` : undefined,
168
187
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
169
188
  style: [styles.iconWrap, {
189
+ width: iconSize + 8,
190
+ height: iconSize + 8,
170
191
  transform: [{
171
192
  scale
172
193
  }]
173
194
  }],
174
195
  children: [renderIcon({
175
196
  color,
176
- size: ICON_SIZE,
197
+ size: iconSize,
177
198
  focused: isActive
178
199
  }), badge ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
179
200
  style: [badge.isDot ? styles.badgeDot : styles.badgePill, {
@@ -201,6 +222,7 @@ const BottomNavigation = exports.BottomNavigation = /*#__PURE__*/(0, _react.forw
201
222
  pointerEvents: "none",
202
223
  style: [styles.underline, indicatorPosition === 'top' ? styles.underlineTop : styles.underlineBottom, {
203
224
  width: tabWidth,
225
+ height: tokens?.underlineHeight ?? DEFAULT_UNDERLINE_HEIGHT,
204
226
  backgroundColor: theme.colors.primary,
205
227
  transform: [{
206
228
  translateX: indicatorTranslateX
@@ -231,8 +253,8 @@ const buildStyles = theme => _reactNative.StyleSheet.create({
231
253
  gap: 2
232
254
  },
233
255
  iconWrap: {
234
- width: ICON_SIZE + 8,
235
- height: ICON_SIZE + 8,
256
+ width: DEFAULT_ICON_SIZE + 8,
257
+ height: DEFAULT_ICON_SIZE + 8,
236
258
  alignItems: 'center',
237
259
  justifyContent: 'center',
238
260
  position: 'relative'
@@ -250,7 +272,7 @@ const buildStyles = theme => _reactNative.StyleSheet.create({
250
272
  underline: {
251
273
  position: 'absolute',
252
274
  left: 0,
253
- height: UNDERLINE_HEIGHT
275
+ height: DEFAULT_UNDERLINE_HEIGHT
254
276
  },
255
277
  underlineBottom: {
256
278
  bottom: -6,
@@ -47,7 +47,6 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
47
47
  onAnimate,
48
48
  enablePanDownToClose = true,
49
49
  enableBackdropPress = true,
50
- backdropOpacity = 0.5,
51
50
  keyboardBehavior = 'none',
52
51
  mode = 'modal',
53
52
  handleIndicatorStyle,
@@ -89,6 +88,11 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
89
88
  // synchronously on open and unmount only after the close animation finishes
90
89
  // so the slide-down stays visible.
91
90
  const [modalVisible, setModalVisible] = (0, _react.useState)(false);
91
+ // Inline-mode mirror of modalVisible: gates the absoluteFill backdrop +
92
+ // sheet tree so a closed inline sheet doesn't sit over the parent dimming
93
+ // it and swallowing touches. Set true on expand, cleared in
94
+ // markAnimationDone once the close animation completes.
95
+ const [inlineMounted, setInlineMounted] = (0, _react.useState)(false);
92
96
 
93
97
  // Convert a snap-point index → translateY position. -1 = closed.
94
98
  const yForIndex = (0, _react.useCallback)(idx => {
@@ -116,18 +120,20 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
116
120
  }, [onAnimate, translateY]);
117
121
  const markAnimationDone = (0, _react.useCallback)(() => {
118
122
  isAnimatingRef.current = false;
119
- // If we just finished a close animation, unmount the modal wrapper.
120
- if (mode === 'modal' && currentIndexShared.value < 0) {
121
- setModalVisible(false);
123
+ // If we just finished a close animation, unmount the sheet wrapper.
124
+ if (currentIndexShared.value < 0) {
125
+ if (mode === 'modal') setModalVisible(false);else setInlineMounted(false);
122
126
  }
123
127
  }, [mode, currentIndexShared]);
124
128
  const expand = (0, _react.useCallback)(idx => {
125
129
  const target = typeof idx === 'number' ? clamp(idx, 0, resolvedSnapPoints.length - 1) : currentIndex >= 0 ? currentIndex : 0;
126
130
  const fromIndex = currentIndexShared.value;
127
131
  const to = yForIndex(target);
128
- // Mount the Modal before kicking off the spring so the sheet has a
129
- // host to animate into.
130
- if (mode === 'modal') setModalVisible(true);
132
+ // Mount the host (Modal in modal mode, inline overlay in inline mode)
133
+ // before kicking off the spring so the sheet has somewhere to animate
134
+ // into. Inline mode also gates the backdrop on this so a closed sheet
135
+ // doesn't dim the parent.
136
+ if (mode === 'modal') setModalVisible(true);else setInlineMounted(true);
131
137
  // Reset translateY to the closed position so the first open animates
132
138
  // up from off-screen rather than snapping in place.
133
139
  if (fromIndex < 0) {
@@ -287,27 +293,31 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
287
293
  }, [keyboardBehavior, keyboardOffset]);
288
294
 
289
295
  // ───────── Animated styles ─────────
296
+ const safeAreaTop = insets.top;
290
297
  const sheetStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
291
- // Don't push past the screen top — keyboard offset is clamped to minTopY.
292
298
  const yWithKb = translateY.value + keyboardOffset.value;
293
- const clamped = yWithKb < minTopY ? minTopY : yWithKb;
299
+ // When the keyboard is up, allow the sheet to slide above its natural
300
+ // max-snap-point top (`minTopY`) so the input area stays visible. We still
301
+ // clamp to the safe-area top so the sheet doesn't disappear under the
302
+ // status bar / notch.
303
+ const lowerBound = keyboardOffset.value < 0 ? safeAreaTop : minTopY;
304
+ const clamped = yWithKb < lowerBound ? lowerBound : yWithKb;
305
+ // Animate `top` (layout prop) instead of `transform: translateY`
306
+ // (visual only). Layout-prop animation under Reanimated still runs on
307
+ // the UI thread, but crucially the sheet's *hit-test box* moves with
308
+ // its visual position. With translateY the layout box stayed parked
309
+ // at top:0..maxSnap regardless of visual offset, so:
310
+ // (a) the empty top half intercepted backdrop taps (worked around
311
+ // previously via pointerEvents="box-none"), and
312
+ // (b) drag gestures on the handle could be claimed by sibling
313
+ // gesture handlers because the actual sheet view was effectively
314
+ // hidden from the responder chain.
315
+ // Animating `top` collapses both problems into nothing — visible area
316
+ // == hit area — so we can drop the box-none hack too.
294
317
  return {
295
- transform: [{
296
- translateY: clamped
297
- }]
318
+ top: clamped
298
319
  };
299
320
  });
300
- const backdropStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
301
- // 0 opacity when sheet is closed, full backdropOpacity at minSnap height (and above).
302
- const closedAt = screenHeight;
303
- const openAt = screenHeight - minSnapPoint;
304
- const opacity = (0, _reactNativeReanimated.interpolate)(translateY.value, [closedAt, openAt], [0, backdropOpacity], _reactNativeReanimated.Extrapolation.CLAMP);
305
- return {
306
- opacity,
307
- // Disable hit-test entirely when fully closed so it doesn't swallow taps.
308
- pointerEvents: translateY.value >= closedAt - 0.5 ? 'none' : 'auto'
309
- };
310
- }, [backdropOpacity, minSnapPoint, screenHeight]);
311
321
  const isExpanded = currentIndex >= 0;
312
322
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
313
323
  const handleBackdropPress = (0, _react.useCallback)(() => {
@@ -316,41 +326,51 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
316
326
  close();
317
327
  }, [enableBackdropPress, close]);
318
328
 
319
- // Don't render the heavy gesture tree at all when nothing's been opened yet.
320
- // For inline mode we keep the legacy "mount on first open" behavior; modal
321
- // mode is gated entirely by `modalVisible`.
322
- const everOpenedRef = (0, _react.useRef)(false);
323
- if (isExpanded || controlledIndex !== undefined) {
324
- everOpenedRef.current = true;
325
- }
326
- if (mode === 'inline' && !everOpenedRef.current) {
329
+ // RNGH Tap gesture for the backdrop. Plain RN Pressable on a sibling of a
330
+ // gesture-handler/reanimated sheet doesn't fire reliably on RN 0.85 / Fabric
331
+ // (the gesture system swallows the touch sequence). gorhom/bottom-sheet uses
332
+ // the same Gesture.Tap() pattern for the same reason.
333
+ const backdropTapGesture = (0, _react.useMemo)(() => _reactNativeGestureHandler.Gesture.Tap().maxDuration(250).onEnd((_e, success) => {
334
+ 'worklet';
335
+
336
+ if (!success) return;
337
+ (0, _reactNativeReanimated.runOnJS)(handleBackdropPress)();
338
+ }), [handleBackdropPress]);
339
+
340
+ // Don't render the backdrop / sheet tree when the sheet is fully closed.
341
+ // Inline: gated by `inlineMounted` (set in expand, cleared in
342
+ // markAnimationDone after close animation) — keeps an idle inline sheet
343
+ // from sitting over the parent and swallowing touches.
344
+ // Modal: gated by `modalVisible` for the same reason.
345
+ if (mode === 'inline' && !inlineMounted) {
327
346
  return null;
328
347
  }
329
348
  if (mode === 'modal' && !modalVisible) {
330
349
  return null;
331
350
  }
332
351
  const sheetTree = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
333
- style: _reactNative.StyleSheet.absoluteFill,
334
- pointerEvents: "box-none",
352
+ collapsable: false
353
+ // Modal mode: the backdrop is the modal's root, so it fills via flex.
354
+ // Inline mode: the backdrop overlays the parent, so it positions absolute.
355
+ ,
356
+ style: [mode === 'modal' ? styles.backdropModal : styles.backdropInline, {
357
+ backgroundColor: theme.colors.background.overlay
358
+ }],
335
359
  testID: testID,
336
360
  accessibilityViewIsModal: accessibilityViewIsModal ?? isExpanded,
337
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
338
- style: [styles.backdrop, {
339
- backgroundColor: theme.colors.background.overlay
340
- }, backdropStyle],
341
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
342
- style: _reactNative.StyleSheet.absoluteFill,
343
- onPress: handleBackdropPress,
361
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
362
+ gesture: backdropTapGesture,
363
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
364
+ style: _reactNative.StyleSheet.absoluteFillObject,
344
365
  accessibilityRole: "button",
345
- accessibilityLabel: "Close bottom sheet",
346
- disabled: !enableBackdropPress || !isExpanded
366
+ accessibilityLabel: "Close bottom sheet"
347
367
  })
348
368
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
349
369
  gesture: panGesture,
350
370
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.View, {
351
371
  // 'dialog' is a valid platform role on web/iOS; RN's typings list it as a string union
352
372
  // that varies by platform — cast keeps strict-mode happy.
353
- accessibilityRole: 'dialog',
373
+ accessibilityRole: "alert",
354
374
  accessibilityLabel: accessibilityLabel,
355
375
  accessibilityViewIsModal: accessibilityViewIsModal ?? isExpanded,
356
376
  style: [styles.sheet, {
@@ -366,7 +386,7 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
366
386
  pointerEvents: "box-none",
367
387
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
368
388
  style: [styles.handle, {
369
- backgroundColor: theme.colors.border.primary
389
+ backgroundColor: theme.components.bottomSheet?.handleColor ?? theme.colors.border.primary
370
390
  }, handleIndicatorStyle]
371
391
  })
372
392
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
@@ -381,14 +401,17 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
381
401
  transparent: true,
382
402
  visible: modalVisible,
383
403
  onRequestClose: close,
384
- statusBarTranslucent: true,
385
- presentationStyle: "overFullScreen",
404
+ statusBarTranslucent: true
405
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
406
+ // @ts-ignore — typed in RN 0.73+, the runtime prop exists on 0.71+
407
+ ,
408
+ navigationBarTranslucent: true,
386
409
  animationType: "none",
387
410
  supportedOrientations: ['portrait', 'landscape'],
388
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureHandlerRootView, {
411
+ children: _reactNative.Platform.OS === 'android' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureHandlerRootView, {
389
412
  style: styles.modalRoot,
390
413
  children: sheetTree
391
- })
414
+ }) : sheetTree
392
415
  });
393
416
  }
394
417
  return sheetTree;
@@ -408,14 +431,26 @@ const resolveSnapPoints = (points, screenH) => {
408
431
  };
409
432
  const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
410
433
  const buildStyles = _theme => _reactNative.StyleSheet.create({
411
- backdrop: {
434
+ backdropModal: {
435
+ // The backdrop is the modal's root View. On Fabric, an absolute-
436
+ // positioned root inside RNModal has no positioned ancestor and
437
+ // collapses to zero size, taking the scrim with it. `flex: 1` fills
438
+ // the modal content area reliably.
439
+ flex: 1
440
+ },
441
+ backdropInline: {
442
+ // Inline mode: overlay the parent. Parent must be positioned for this
443
+ // to take effect (the consumer is expected to render BottomSheet inside
444
+ // a relatively-positioned container).
412
445
  ..._reactNative.StyleSheet.absoluteFillObject
413
446
  },
414
447
  sheet: {
415
448
  position: 'absolute',
416
449
  left: 0,
417
450
  right: 0,
418
- top: 0,
451
+ // `top` is driven by the animated style (see sheetStyle). Omitted
452
+ // here so the static `0` doesn't fight the animated value during
453
+ // initial paint.
419
454
  overflow: 'hidden'
420
455
  },
421
456
  handleRow: {