@webority/mobile-ui 0.15.0 → 0.16.1

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 (161) hide show
  1. package/lib/commonjs/components/Accordion/Accordion.js +1 -1
  2. package/lib/commonjs/components/AmountSlider/AmountSlider.js +1 -1
  3. package/lib/commonjs/components/AnimatePresence/AnimatePresence.js +1 -1
  4. package/lib/commonjs/components/AppBar/AppBar.js +1 -1
  5. package/lib/commonjs/components/AsyncBlock/AsyncBlock.js +1 -1
  6. package/lib/commonjs/components/Banner/Banner.js +1 -1
  7. package/lib/commonjs/components/BottomSheet/BottomSheet.js +1 -1
  8. package/lib/commonjs/components/Button/Button.js +1 -1
  9. package/lib/commonjs/components/Calendar/Calendar.js +1 -1
  10. package/lib/commonjs/components/Card/Card.js +1 -1
  11. package/lib/commonjs/components/Carousel/Carousel.js +1 -1
  12. package/lib/commonjs/components/Chip/Chip.js +1 -1
  13. package/lib/commonjs/components/DatePicker/DatePicker.js +1 -1
  14. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +1 -1
  15. package/lib/commonjs/components/Drawer/Drawer.js +1 -1
  16. package/lib/commonjs/components/EmptyState/EmptyState.js +1 -1
  17. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +1 -1
  18. package/lib/commonjs/components/IconButton/IconButton.js +1 -1
  19. package/lib/commonjs/components/ListItem/ListItem.js +1 -1
  20. package/lib/commonjs/components/LoaderOverlay/LoaderOverlay.js +1 -1
  21. package/lib/commonjs/components/Menu/MenuSurface.js +1 -1
  22. package/lib/commonjs/components/MessageBubble/MessageBubble.js +1 -1
  23. package/lib/commonjs/components/Modal/Modal.js +1 -1
  24. package/lib/commonjs/components/OTPInput/OTPInput.js +1 -1
  25. package/lib/commonjs/components/OnboardingPager/OnboardingPager.js +1 -1
  26. package/lib/commonjs/components/OptionSheet/OptionSheet.js +1 -1
  27. package/lib/commonjs/components/ProgressBar/ProgressBar.js +1 -1
  28. package/lib/commonjs/components/Screen/Screen.js +1 -0
  29. package/lib/commonjs/components/Screen/index.js +1 -0
  30. package/lib/commonjs/components/SignaturePad/SignaturePad.js +1 -1
  31. package/lib/commonjs/components/Skeleton/Skeleton.js +1 -1
  32. package/lib/commonjs/components/Skeleton/SkeletonContent.js +1 -1
  33. package/lib/commonjs/components/Skeleton/SkeletonProvider.js +1 -1
  34. package/lib/commonjs/components/Skeleton/index.js +1 -1
  35. package/lib/commonjs/components/Spinner/Spinner.js +1 -1
  36. package/lib/commonjs/components/TagInput/TagInput.js +1 -1
  37. package/lib/commonjs/components/Text/Text.js +1 -1
  38. package/lib/commonjs/components/TimePicker/TimePicker.js +1 -1
  39. package/lib/commonjs/components/Toast/Toast.js +1 -1
  40. package/lib/commonjs/components/Tooltip/Tooltip.js +1 -1
  41. package/lib/commonjs/components/Tour/Tour.js +1 -1
  42. package/lib/commonjs/components/WheelPicker/Wheel.js +1 -1
  43. package/lib/commonjs/components/WheelPicker/WheelPicker.js +1 -1
  44. package/lib/commonjs/components/index.js +1 -1
  45. package/lib/commonjs/hooks/index.js +1 -1
  46. package/lib/commonjs/hooks/useDragToDismiss.js +1 -1
  47. package/lib/commonjs/hooks/useFieldChain.js +1 -0
  48. package/lib/commonjs/hooks/usePresenceMotion.js +1 -0
  49. package/lib/commonjs/hooks/usePressAnimation.js +1 -1
  50. package/lib/commonjs/hooks/useReducedMotion.js +1 -1
  51. package/lib/commonjs/index.js +1 -1
  52. package/lib/commonjs/network/NetworkStatusBanner.js +1 -1
  53. package/lib/commonjs/theme/tokens.js +1 -1
  54. package/lib/commonjs/utils/hapticUtils.js +1 -1
  55. package/lib/module/components/Accordion/Accordion.js +1 -1
  56. package/lib/module/components/AmountSlider/AmountSlider.js +1 -1
  57. package/lib/module/components/AnimatePresence/AnimatePresence.js +1 -1
  58. package/lib/module/components/AppBar/AppBar.js +1 -1
  59. package/lib/module/components/AsyncBlock/AsyncBlock.js +1 -1
  60. package/lib/module/components/Banner/Banner.js +1 -1
  61. package/lib/module/components/BottomSheet/BottomSheet.js +1 -1
  62. package/lib/module/components/Button/Button.js +1 -1
  63. package/lib/module/components/Calendar/Calendar.js +1 -1
  64. package/lib/module/components/Card/Card.js +1 -1
  65. package/lib/module/components/Carousel/Carousel.js +1 -1
  66. package/lib/module/components/Chip/Chip.js +1 -1
  67. package/lib/module/components/DatePicker/DatePicker.js +1 -1
  68. package/lib/module/components/DateRangePicker/DateRangePicker.js +1 -1
  69. package/lib/module/components/Drawer/Drawer.js +1 -1
  70. package/lib/module/components/EmptyState/EmptyState.js +1 -1
  71. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +1 -1
  72. package/lib/module/components/IconButton/IconButton.js +1 -1
  73. package/lib/module/components/ListItem/ListItem.js +1 -1
  74. package/lib/module/components/LoaderOverlay/LoaderOverlay.js +1 -1
  75. package/lib/module/components/Menu/MenuSurface.js +1 -1
  76. package/lib/module/components/MessageBubble/MessageBubble.js +1 -1
  77. package/lib/module/components/Modal/Modal.js +1 -1
  78. package/lib/module/components/OTPInput/OTPInput.js +1 -1
  79. package/lib/module/components/OnboardingPager/OnboardingPager.js +1 -1
  80. package/lib/module/components/OptionSheet/OptionSheet.js +1 -1
  81. package/lib/module/components/ProgressBar/ProgressBar.js +1 -1
  82. package/lib/module/components/Screen/Screen.js +1 -0
  83. package/lib/module/components/Screen/index.js +1 -0
  84. package/lib/module/components/SignaturePad/SignaturePad.js +1 -1
  85. package/lib/module/components/Skeleton/Skeleton.js +1 -1
  86. package/lib/module/components/Skeleton/SkeletonContent.js +1 -1
  87. package/lib/module/components/Skeleton/SkeletonProvider.js +1 -1
  88. package/lib/module/components/Skeleton/index.js +1 -1
  89. package/lib/module/components/Spinner/Spinner.js +1 -1
  90. package/lib/module/components/TagInput/TagInput.js +1 -1
  91. package/lib/module/components/Text/Text.js +1 -1
  92. package/lib/module/components/TimePicker/TimePicker.js +1 -1
  93. package/lib/module/components/Toast/Toast.js +1 -1
  94. package/lib/module/components/Tooltip/Tooltip.js +1 -1
  95. package/lib/module/components/Tour/Tour.js +1 -1
  96. package/lib/module/components/WheelPicker/Wheel.js +1 -1
  97. package/lib/module/components/WheelPicker/WheelPicker.js +1 -1
  98. package/lib/module/components/index.js +1 -1
  99. package/lib/module/hooks/index.js +1 -1
  100. package/lib/module/hooks/useDragToDismiss.js +1 -1
  101. package/lib/module/hooks/useFieldChain.js +1 -0
  102. package/lib/module/hooks/usePresenceMotion.js +1 -0
  103. package/lib/module/hooks/usePressAnimation.js +1 -1
  104. package/lib/module/hooks/useReducedMotion.js +1 -1
  105. package/lib/module/index.js +1 -1
  106. package/lib/module/network/NetworkStatusBanner.js +1 -1
  107. package/lib/module/theme/tokens.js +1 -1
  108. package/lib/module/utils/hapticUtils.js +1 -1
  109. package/lib/typescript/commonjs/components/AnimatePresence/AnimatePresence.d.ts +5 -5
  110. package/lib/typescript/commonjs/components/AsyncBlock/AsyncBlock.d.ts +11 -6
  111. package/lib/typescript/commonjs/components/BottomSheet/BottomSheet.d.ts +8 -2
  112. package/lib/typescript/commonjs/components/Button/Button.d.ts +6 -3
  113. package/lib/typescript/commonjs/components/Card/Card.d.ts +1 -1
  114. package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +2 -0
  115. package/lib/typescript/commonjs/components/ListItem/ListItem.d.ts +1 -1
  116. package/lib/typescript/commonjs/components/MessageBubble/MessageBubble.d.ts +6 -3
  117. package/lib/typescript/commonjs/components/OTPInput/OTPInput.d.ts +1 -2
  118. package/lib/typescript/commonjs/components/Screen/Screen.d.ts +39 -0
  119. package/lib/typescript/commonjs/components/Screen/index.d.ts +3 -0
  120. package/lib/typescript/commonjs/components/SignaturePad/SignaturePad.d.ts +6 -0
  121. package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +2 -2
  122. package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +3 -11
  123. package/lib/typescript/commonjs/components/Skeleton/index.d.ts +1 -1
  124. package/lib/typescript/commonjs/components/WheelPicker/Wheel.d.ts +2 -0
  125. package/lib/typescript/commonjs/components/WheelPicker/WheelPicker.d.ts +5 -0
  126. package/lib/typescript/commonjs/components/index.d.ts +3 -1
  127. package/lib/typescript/commonjs/hooks/index.d.ts +4 -0
  128. package/lib/typescript/commonjs/hooks/useDragToDismiss.d.ts +10 -2
  129. package/lib/typescript/commonjs/hooks/useFieldChain.d.ts +10 -0
  130. package/lib/typescript/commonjs/hooks/usePresenceMotion.d.ts +14 -0
  131. package/lib/typescript/commonjs/hooks/usePressAnimation.d.ts +2 -2
  132. package/lib/typescript/commonjs/hooks/useReducedMotion.d.ts +0 -6
  133. package/lib/typescript/commonjs/index.d.ts +2 -2
  134. package/lib/typescript/commonjs/theme/types.d.ts +4 -0
  135. package/lib/typescript/module/components/AnimatePresence/AnimatePresence.d.ts +5 -5
  136. package/lib/typescript/module/components/AsyncBlock/AsyncBlock.d.ts +11 -6
  137. package/lib/typescript/module/components/BottomSheet/BottomSheet.d.ts +8 -2
  138. package/lib/typescript/module/components/Button/Button.d.ts +6 -3
  139. package/lib/typescript/module/components/Card/Card.d.ts +1 -1
  140. package/lib/typescript/module/components/Carousel/Carousel.d.ts +2 -0
  141. package/lib/typescript/module/components/ListItem/ListItem.d.ts +1 -1
  142. package/lib/typescript/module/components/MessageBubble/MessageBubble.d.ts +6 -3
  143. package/lib/typescript/module/components/OTPInput/OTPInput.d.ts +1 -2
  144. package/lib/typescript/module/components/Screen/Screen.d.ts +39 -0
  145. package/lib/typescript/module/components/Screen/index.d.ts +3 -0
  146. package/lib/typescript/module/components/SignaturePad/SignaturePad.d.ts +6 -0
  147. package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +2 -2
  148. package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +3 -11
  149. package/lib/typescript/module/components/Skeleton/index.d.ts +1 -1
  150. package/lib/typescript/module/components/WheelPicker/Wheel.d.ts +2 -0
  151. package/lib/typescript/module/components/WheelPicker/WheelPicker.d.ts +5 -0
  152. package/lib/typescript/module/components/index.d.ts +3 -1
  153. package/lib/typescript/module/hooks/index.d.ts +4 -0
  154. package/lib/typescript/module/hooks/useDragToDismiss.d.ts +10 -2
  155. package/lib/typescript/module/hooks/useFieldChain.d.ts +10 -0
  156. package/lib/typescript/module/hooks/usePresenceMotion.d.ts +14 -0
  157. package/lib/typescript/module/hooks/usePressAnimation.d.ts +2 -2
  158. package/lib/typescript/module/hooks/useReducedMotion.d.ts +0 -6
  159. package/lib/typescript/module/index.d.ts +2 -2
  160. package/lib/typescript/module/theme/types.d.ts +4 -0
  161. package/package.json +3 -3
@@ -1 +1 @@
1
- "use strict";import{forwardRef,useCallback,useEffect,useImperativeHandle,useMemo,useRef,useState}from"react";import{Dimensions,Pressable,StyleSheet,View}from"react-native";import{Gesture,GestureDetector}from"react-native-gesture-handler";import Animated,{Extrapolation,interpolate,runOnJS,useAnimatedStyle,useSharedValue,withSpring}from"react-native-reanimated";import{useSafeAreaInsets}from"react-native-safe-area-context";import{useTheme}from"../../theme/index.js";import{resolveHaptic,triggerHaptic}from"../../utils/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const DEFAULT_CLOSE_VELOCITY_THRESHOLD=1e3,DEFAULT_DRAG_ACTIVATION_OFFSET=10,Drawer=forwardRef((e,t)=>{const{visible:a,defaultVisible:r=!1,onChange:s,side:o="left",width:i,enableSwipe:l=!0,enableBackdropPress:n=!0,backdropOpacity:u=.5,haptic:c,containerStyle:d,children:p,accessibilityLabel:f,testID:h}=e,m=useTheme(),b=useSafeAreaInsets(),g="boolean"==typeof a,S=m.components.drawer,v=S?.closeVelocityThreshold??1e3,w=S?.dragActivationOffset??10,[y,x]=useState(()=>Dimensions.get("window"));useEffect(()=>{const e=Dimensions.addEventListener("change",({window:e})=>x(e));return()=>e.remove()},[]);const k="left"===o||"right"===o,D=useMemo(()=>resolveSize(i,k,y),[i,k,y]),C=useMemo(()=>{switch(o){case"left":case"top":return-D;case"right":case"bottom":return D}},[o,D]),E=useSharedValue(r?0:C),A=useSharedValue(r?0:C),[M,O]=useState(r),V=useSharedValue(r);useEffect(()=>{M||(E.value=C,A.value=C)},[C,M,E,A]);const _=m.motion.spring.snappy,j=useCallback(()=>{E.value=withSpring(0,_)},[E,_]),L=useCallback(()=>{E.value=withSpring(C,_)},[E,C,_]),T=useCallback(e=>{O(t=>t===e?t:(s?.(e),e)),V.value=e},[s,V]),R=useCallback(()=>{T(!0),j()},[T,j]),I=useCallback(()=>{T(!1),L()},[T,L]),F=useCallback(()=>{M?I():R()},[M,R,I]);useImperativeHandle(t,()=>({open:R,close:I,toggle:F}),[R,I,F]),useEffect(()=>{g&&a!==M&&(a?R():I())},[a]);const H=useMemo(()=>{const e=C,t=o,a=l;let r=Gesture.Pan();return r=k?r.activeOffsetX([-w,w]).failOffsetY([-15,15]):r.activeOffsetY([-w,w]).failOffsetX([-15,15]),r.onStart(()=>{"worklet";a&&(A.value=E.value)}).onUpdate(t=>{"worklet";if(!a)return;const r=k?t.translationX:t.translationY,s=A.value+r,o=Math.min(0,e),i=Math.max(0,e);E.value=s<o?o+.25*(s-o):s>i?i+.25*(s-i):s}).onEnd(r=>{"worklet";if(!a)return;const s=k?r.velocityX:r.velocityY,o=E.value;let i=!1;i="left"===t||"top"===t?s<-v:s>v;const l=Math.abs(e),n=Math.abs(o)/l;i||n>.5?(runOnJS(T)(!1),E.value=withSpring(e,_)):(runOnJS(T)(!0),E.value=withSpring(0,_))})},[C,A,l,k,E,T,o,_,v,w]),P=useAnimatedStyle(()=>k?{transform:[{translateX:E.value}]}:{transform:[{translateY:E.value}]}),Y=useAnimatedStyle(()=>({opacity:interpolate(E.value,[C,0],[0,u],Extrapolation.CLAMP),pointerEvents:Math.abs(E.value-C)<.5?"none":"auto"}),[C,u]),G=useMemo(()=>buildStyles(m),[m]),N=useCallback(()=>{if(!n)return;const e=resolveHaptic(c,"selection");e&&triggerHaptic(e),I()},[n,I,c]),X=useMemo(()=>{switch(o){case"left":return{position:"absolute",top:0,bottom:0,left:0,width:D,paddingTop:b.top,paddingBottom:b.bottom,paddingLeft:b.left};case"right":return{position:"absolute",top:0,bottom:0,right:0,width:D,paddingTop:b.top,paddingBottom:b.bottom,paddingRight:b.right};case"top":return{position:"absolute",top:0,left:0,right:0,height:D,paddingTop:b.top,paddingLeft:b.left,paddingRight:b.right};case"bottom":return{position:"absolute",bottom:0,left:0,right:0,height:D,paddingBottom:b.bottom,paddingLeft:b.left,paddingRight:b.right}}},[o,D,b]),B=useRef(r);return M&&(B.current=!0),B.current?_jsxs(View,{style:StyleSheet.absoluteFill,pointerEvents:"box-none",testID:h,accessibilityViewIsModal:M,children:[_jsx(Animated.View,{style:[G.backdrop,{backgroundColor:m.colors.background.overlay},Y],children:_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:N,accessibilityRole:"button",accessibilityLabel:"Close drawer",disabled:!n||!M})}),_jsx(GestureDetector,{gesture:H,children:_jsx(Animated.View,{accessibilityRole:"alert",accessibilityLabel:f??"Drawer",style:[X,{backgroundColor:m.colors.background.elevated,...m.shadows.xl},d,P],children:_jsx(View,{style:G.content,children:p})})})]}):null});Drawer.displayName="Drawer";const resolveSize=(e,t,a)=>{if("number"==typeof e)return e;if("string"==typeof e){const r=parseFloat(e);if(Number.isNaN(r))return t?280:Math.round(.4*a.height);return r/100*(t?a.width:a.height)}return t?280:Math.round(.4*a.height)},buildStyles=e=>StyleSheet.create({backdrop:{...StyleSheet.absoluteFill},content:{flex:1}});export{Drawer};export default Drawer;
1
+ "use strict";import{forwardRef,useCallback,useEffect,useImperativeHandle,useMemo,useRef,useState}from"react";import{Dimensions,Pressable,StyleSheet,View}from"react-native";import{Gesture,GestureDetector}from"react-native-gesture-handler";import Animated,{Extrapolation,interpolate,runOnJS,useAnimatedStyle,useSharedValue,withSpring,withTiming}from"react-native-reanimated";import{useSafeAreaInsets}from"react-native-safe-area-context";import{PRESENCE_REDUCE_MOTION,usePresenceMotion}from"../../hooks/usePresenceMotion.js";import{useTheme}from"../../theme/index.js";import{resolveHaptic,triggerHaptic}from"../../utils/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const DEFAULT_CLOSE_VELOCITY_THRESHOLD=1e3,DEFAULT_DRAG_ACTIVATION_OFFSET=10,Drawer=forwardRef((e,t)=>{const{visible:a,defaultVisible:i=!1,onChange:o,side:r="left",width:s,enableSwipe:n=!0,enableBackdropPress:l=!0,backdropOpacity:u=.5,haptic:c,containerStyle:d,children:p,accessibilityLabel:h,testID:f}=e,m=useTheme(),g=usePresenceMotion(),b=g.reduced,v=g.duration("normal"),S=g.duration("fast"),w=useSafeAreaInsets(),E="boolean"==typeof a,y=m.components.drawer,M=y?.closeVelocityThreshold??1e3,C=y?.dragActivationOffset??10,[O,_]=useState(()=>Dimensions.get("window"));useEffect(()=>{const e=Dimensions.addEventListener("change",({window:e})=>_(e));return()=>e.remove()},[]);const T="left"===r||"right"===r,k=useMemo(()=>resolveSize(s,T,O),[s,T,O]),x=useMemo(()=>{switch(r){case"left":case"top":return-k;case"right":case"bottom":return k}},[r,k]),D=useSharedValue(i?0:x),R=useSharedValue(i?0:x),A=useSharedValue(i?1:0),[I,N]=useState(i),V=useSharedValue(i);useEffect(()=>{I||b||(D.value=x,R.value=x)},[x,I,D,R,b]);const j=m.motion.spring.snappy,P=useCallback(()=>{if(b)return D.value=0,void(A.value=withTiming(1,{duration:v,reduceMotion:PRESENCE_REDUCE_MOTION}));A.value=1,D.value=withSpring(0,j)},[D,A,j,b,v]),L=useCallback(()=>{b?A.value=withTiming(0,{duration:S,reduceMotion:PRESENCE_REDUCE_MOTION},e=>{"worklet";e&&(D.value=x)}):D.value=withSpring(x,j)},[D,A,x,j,b,S]),F=useCallback(e=>{N(t=>t===e?t:(o?.(e),e)),V.value=e},[o,V]),H=useCallback(()=>{F(!0),P()},[F,P]),U=useCallback(()=>{F(!1),L()},[F,L]),Y=useCallback(()=>{I?U():H()},[I,H,U]);useImperativeHandle(t,()=>({open:H,close:U,toggle:Y}),[H,U,Y]),useEffect(()=>{E&&a!==I&&(a?H():U())},[a]);const G=useMemo(()=>{const e=x,t=r,a=n;let i=Gesture.Pan();return i=T?i.activeOffsetX([-C,C]).failOffsetY([-15,15]):i.activeOffsetY([-C,C]).failOffsetX([-15,15]),i.onStart(()=>{"worklet";a&&(R.value=D.value)}).onUpdate(t=>{"worklet";if(!a)return;const i=T?t.translationX:t.translationY,o=R.value+i,r=Math.min(0,e),s=Math.max(0,e);D.value=o<r?r+.25*(o-r):o>s?s+.25*(o-s):o}).onEnd(i=>{"worklet";if(!a)return;const o=T?i.velocityX:i.velocityY,r=D.value;let s=!1;s="left"===t||"top"===t?o<-M:o>M;const n=Math.abs(e),l=Math.abs(r)/n;s||l>.5?(runOnJS(F)(!1),b?A.value=withTiming(0,{duration:S,reduceMotion:PRESENCE_REDUCE_MOTION},t=>{"worklet";t&&(D.value=e)}):D.value=withSpring(e,j)):(runOnJS(F)(!0),b?(D.value=0,A.value=withTiming(1,{duration:v,reduceMotion:PRESENCE_REDUCE_MOTION})):D.value=withSpring(0,j))})},[x,R,n,T,D,A,F,r,j,M,C,b,v,S]),X=useAnimatedStyle(()=>T?{opacity:A.value,transform:[{translateX:D.value}]}:{opacity:A.value,transform:[{translateY:D.value}]}),B=useAnimatedStyle(()=>({opacity:interpolate(D.value,[x,0],[0,u],Extrapolation.CLAMP)*A.value,pointerEvents:Math.abs(D.value-x)<.5?"none":"auto"}),[x,u]),J=useMemo(()=>buildStyles(m),[m]),z=useCallback(()=>{if(!l)return;const e=resolveHaptic(c,"selection");e&&triggerHaptic(e),U()},[l,U,c]),q=useMemo(()=>{switch(r){case"left":return{position:"absolute",top:0,bottom:0,left:0,width:k,paddingTop:w.top,paddingBottom:w.bottom,paddingLeft:w.left};case"right":return{position:"absolute",top:0,bottom:0,right:0,width:k,paddingTop:w.top,paddingBottom:w.bottom,paddingRight:w.right};case"top":return{position:"absolute",top:0,left:0,right:0,height:k,paddingTop:w.top,paddingLeft:w.left,paddingRight:w.right};case"bottom":return{position:"absolute",bottom:0,left:0,right:0,height:k,paddingBottom:w.bottom,paddingLeft:w.left,paddingRight:w.right}}},[r,k,w]),K=useRef(i);return I&&(K.current=!0),K.current?_jsxs(View,{style:StyleSheet.absoluteFill,pointerEvents:"box-none",testID:f,accessibilityViewIsModal:I,children:[_jsx(Animated.View,{style:[J.backdrop,{backgroundColor:m.colors.background.overlay},B],children:_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:z,accessibilityRole:"button",accessibilityLabel:"Close drawer",disabled:!l||!I})}),_jsx(GestureDetector,{gesture:G,children:_jsx(Animated.View,{accessibilityRole:"alert",accessibilityLabel:h??"Drawer",style:[q,{backgroundColor:m.colors.background.elevated,...m.shadows.xl},d,X],children:_jsx(View,{style:J.content,children:p})})})]}):null});Drawer.displayName="Drawer";const resolveSize=(e,t,a)=>{if("number"==typeof e)return e;if("string"==typeof e){const i=parseFloat(e);if(Number.isNaN(i))return t?280:Math.round(.4*a.height);return i/100*(t?a.width:a.height)}return t?280:Math.round(.4*a.height)},buildStyles=e=>StyleSheet.create({backdrop:{...StyleSheet.absoluteFill},content:{flex:1}});export{Drawer};export default Drawer;
@@ -1 +1 @@
1
- "use strict";import{forwardRef,useMemo}from"react";import{Animated,Pressable,StyleSheet,Text,View}from"react-native";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{fontFor,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{triggerHaptic}from"../../utils/hapticUtils.js";import{SquircleFill,useSquircle}from"../SquircleFill/SquircleFill.js";import{jsx as _jsx,Fragment as _Fragment,jsxs as _jsxs}from"react/jsx-runtime";const SIZE_FALLBACK={sm:{iconSize:48,titleFontSize:"lg",descriptionFontSize:"sm",paddingVertical:"lg",titleGap:"md",descriptionGap:"xs"},md:{iconSize:64,titleFontSize:"xl",descriptionFontSize:"base",paddingVertical:"xl",titleGap:"md",descriptionGap:"xs"},lg:{iconSize:80,titleFontSize:"2xl",descriptionFontSize:"base",paddingVertical:"2xl",titleGap:"md",descriptionGap:"xs"}},sizeFor=(e,t)=>{const i={...SIZE_FALLBACK[t],...e.components.emptyState?.[t]??{}};return{iconSize:i.iconSize,titleSize:e.typography.fontSize[i.titleFontSize],descriptionSize:e.typography.fontSize[i.descriptionFontSize],paddingVertical:e.spacing[i.paddingVertical],titleGap:e.spacing[i.titleGap],descriptionGap:e.spacing[i.descriptionGap]}},ActionButton=({action:e,variant:t})=>{const i=useTheme(),{scale:r,pressIn:o,pressOut:s}=usePressAnimation({enabled:!0}),n=useMemo(()=>buildActionStyles(i),[i]),l="primary"===t,a=useSquircle(!0,i.radius.md),fillFor=e=>l?i.colors.primary:e?i.colors.surface.pressed:"transparent";return _jsx(Animated.View,{style:{transform:[{scale:r}]},children:_jsx(Pressable,{onPress:()=>{triggerHaptic("selection"),e.onPress()},onPressIn:o,onPressOut:s,accessibilityRole:"button",accessibilityLabel:e.accessibilityLabel??e.label,accessibilityHint:e.accessibilityHint,testID:e.testID,onLayout:a.onLayout,android_ripple:{color:l?i.colors.primaryHover:i.colors.surface.pressed,borderless:!1},style:({pressed:e})=>[n.button,l?n.buttonPrimary:n.buttonSecondary,!e||l||a.active?null:n.buttonSecondaryPressed,a.active?n.buttonSquircleHost:null],children:({pressed:t})=>_jsxs(_Fragment,{children:[a.active&&a.size?_jsx(SquircleFill,{width:a.size.width,height:a.size.height,radius:i.radius.md,fill:fillFor(t),stroke:l?void 0:i.colors.border.primary,strokeWidth:l?0:1,outset:l?0:1}):null,_jsx(Text,{style:[n.buttonText,l?n.buttonTextPrimary:n.buttonTextSecondary],numberOfLines:1,children:e.label})]})})})},EmptyState=forwardRef((e,t)=>{const{icon:i,title:r,description:o,action:s,secondaryAction:n,size:l="md",fill:a=!1,style:c,testID:d}=e,p=useTheme(),m=useMemo(()=>sizeFor(p,l),[p,l]),u=useMemo(()=>buildStyles(p),[p]);return _jsxs(View,{ref:t,accessibilityRole:"summary",testID:d,style:[u.root,{paddingVertical:m.paddingVertical},a?u.fill:null,c],children:[i?_jsx(View,{style:[u.iconCircle,{width:m.iconSize,height:m.iconSize,marginBottom:m.titleGap,borderRadius:m.iconSize/2,...smoothCorners}],children:i}):null,_jsx(Text,{style:[u.title,{fontSize:m.titleSize,...fontFor(p,"semibold")}],children:r}),o?_jsx(Text,{style:[u.description,{fontSize:m.descriptionSize,marginTop:m.descriptionGap}],children:o}):null,s||n?_jsxs(View,{style:u.actions,children:[s?_jsx(ActionButton,{action:s,variant:"primary"}):null,n?_jsx(ActionButton,{action:n,variant:"secondary"}):null]}):null]})});EmptyState.displayName="EmptyState";const buildStyles=e=>StyleSheet.create({root:{alignItems:"center",justifyContent:"center",paddingHorizontal:e.spacing.lg},fill:{flexGrow:1},iconCircle:{backgroundColor:e.colors.surface.disabled,alignItems:"center",justifyContent:"center"},title:{color:e.colors.text.primary,textAlign:"center"},description:{color:e.colors.text.secondary,textAlign:"center",maxWidth:320,lineHeight:e.typography.fontSize.base*e.typography.lineHeight.normal},actions:{flexDirection:"row",alignItems:"center",gap:e.spacing.sm,marginTop:e.spacing.md+e.spacing.xs}}),buildActionStyles=e=>StyleSheet.create({button:{paddingHorizontal:e.spacing.lg,paddingVertical:e.spacing.sm,minHeight:42,borderRadius:e.radius.md,...smoothCorners,alignItems:"center",justifyContent:"center",flexDirection:"row"},buttonPrimary:{backgroundColor:e.colors.primary},buttonSecondary:{backgroundColor:"transparent",borderWidth:1,borderColor:e.colors.border.primary},buttonSecondaryPressed:{backgroundColor:e.colors.surface.pressed},buttonSquircleHost:{backgroundColor:"transparent",borderColor:"transparent",overflow:"visible"},buttonText:{fontSize:e.typography.fontSize.base,...fontFor(e,"semibold")},buttonTextPrimary:{color:e.colors.onPrimary},buttonTextSecondary:{color:e.colors.text.primary}});export{EmptyState};export default EmptyState;
1
+ "use strict";import{forwardRef,useMemo}from"react";import{Animated,Pressable,StyleSheet,Text,View}from"react-native";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{fontFor,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{triggerHaptic}from"../../utils/hapticUtils.js";import{SquircleFill,useSquircle}from"../SquircleFill/SquircleFill.js";import{jsx as _jsx,Fragment as _Fragment,jsxs as _jsxs}from"react/jsx-runtime";const SIZE_FALLBACK={sm:{iconSize:48,titleFontSize:"lg",descriptionFontSize:"sm",paddingVertical:"lg",titleGap:"md",descriptionGap:"xs"},md:{iconSize:64,titleFontSize:"xl",descriptionFontSize:"base",paddingVertical:"xl",titleGap:"md",descriptionGap:"xs"},lg:{iconSize:80,titleFontSize:"2xl",descriptionFontSize:"base",paddingVertical:"2xl",titleGap:"md",descriptionGap:"xs"}},sizeFor=(e,t)=>{const i={...SIZE_FALLBACK[t],...e.components.emptyState?.[t]??{}};return{iconSize:i.iconSize,titleSize:e.typography.fontSize[i.titleFontSize],descriptionSize:e.typography.fontSize[i.descriptionFontSize],paddingVertical:e.spacing[i.paddingVertical],titleGap:e.spacing[i.titleGap],descriptionGap:e.spacing[i.descriptionGap]}},ActionButton=({action:e,variant:t})=>{const i=useTheme(),{style:r,pressIn:o,pressOut:s}=usePressAnimation({enabled:!0}),n=useMemo(()=>buildActionStyles(i),[i]),l="primary"===t,a=useSquircle(!0,i.radius.md),fillFor=e=>l?i.colors.primary:e?i.colors.surface.pressed:"transparent";return _jsx(Animated.View,{style:r,children:_jsx(Pressable,{onPress:()=>{triggerHaptic("selection"),e.onPress()},onPressIn:o,onPressOut:s,accessibilityRole:"button",accessibilityLabel:e.accessibilityLabel??e.label,accessibilityHint:e.accessibilityHint,testID:e.testID,onLayout:a.onLayout,android_ripple:{color:l?i.colors.primaryHover:i.colors.surface.pressed,borderless:!1},style:({pressed:e})=>[n.button,l?n.buttonPrimary:n.buttonSecondary,!e||l||a.active?null:n.buttonSecondaryPressed,a.active?n.buttonSquircleHost:null],children:({pressed:t})=>_jsxs(_Fragment,{children:[a.active&&a.size?_jsx(SquircleFill,{width:a.size.width,height:a.size.height,radius:i.radius.md,fill:fillFor(t),stroke:l?void 0:i.colors.border.primary,strokeWidth:l?0:1,outset:l?0:1}):null,_jsx(Text,{style:[n.buttonText,l?n.buttonTextPrimary:n.buttonTextSecondary],numberOfLines:1,children:e.label})]})})})},EmptyState=forwardRef((e,t)=>{const{icon:i,title:r,description:o,action:s,secondaryAction:n,size:l="md",fill:a=!1,style:c,testID:d}=e,p=useTheme(),m=useMemo(()=>sizeFor(p,l),[p,l]),u=useMemo(()=>buildStyles(p),[p]);return _jsxs(View,{ref:t,accessibilityRole:"summary",testID:d,style:[u.root,{paddingVertical:m.paddingVertical},a?u.fill:null,c],children:[i?_jsx(View,{style:[u.iconCircle,{width:m.iconSize,height:m.iconSize,marginBottom:m.titleGap,borderRadius:m.iconSize/2,...smoothCorners}],children:i}):null,_jsx(Text,{style:[u.title,{fontSize:m.titleSize,...fontFor(p,"semibold")}],children:r}),o?_jsx(Text,{style:[u.description,{fontSize:m.descriptionSize,marginTop:m.descriptionGap}],children:o}):null,s||n?_jsxs(View,{style:u.actions,children:[s?_jsx(ActionButton,{action:s,variant:"primary"}):null,n?_jsx(ActionButton,{action:n,variant:"secondary"}):null]}):null]})});EmptyState.displayName="EmptyState";const buildStyles=e=>StyleSheet.create({root:{alignItems:"center",justifyContent:"center",paddingHorizontal:e.spacing.lg},fill:{flexGrow:1},iconCircle:{backgroundColor:e.colors.surface.disabled,alignItems:"center",justifyContent:"center"},title:{color:e.colors.text.primary,textAlign:"center"},description:{color:e.colors.text.secondary,textAlign:"center",maxWidth:320,lineHeight:e.typography.fontSize.base*e.typography.lineHeight.normal},actions:{flexDirection:"row",alignItems:"center",gap:e.spacing.sm,marginTop:e.spacing.md+e.spacing.xs}}),buildActionStyles=e=>StyleSheet.create({button:{paddingHorizontal:e.spacing.lg,paddingVertical:e.spacing.sm,minHeight:42,borderRadius:e.radius.md,...smoothCorners,alignItems:"center",justifyContent:"center",flexDirection:"row"},buttonPrimary:{backgroundColor:e.colors.primary},buttonSecondary:{backgroundColor:"transparent",borderWidth:1,borderColor:e.colors.border.primary},buttonSecondaryPressed:{backgroundColor:e.colors.surface.pressed},buttonSquircleHost:{backgroundColor:"transparent",borderColor:"transparent",overflow:"visible"},buttonText:{fontSize:e.typography.fontSize.base,...fontFor(e,"semibold")},buttonTextPrimary:{color:e.colors.onPrimary},buttonTextSecondary:{color:e.colors.text.primary}});export{EmptyState};export default EmptyState;
@@ -1 +1 @@
1
- "use strict";import React,{forwardRef,useCallback,useEffect,useMemo,useRef,useState}from"react";import{AccessibilityInfo,Animated,Easing,Platform,Pressable,StyleSheet,Text,View}from"react-native";import Reanimated,{cancelAnimation,Easing as ReanimatedEasing,useAnimatedStyle,useSharedValue,withTiming}from"react-native-reanimated";import{useSafeAreaInsets}from"react-native-safe-area-context";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{useReducedMotion}from"../../hooks/useReducedMotion.js";import{createAnimatedValue,setNativeValue,useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{ACCENT_PRESSED_TINT}from"../../utils/color.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const sizeMap={sm:{diameter:40,iconSize:18,fontSize:13,labelPaddingHorizontal:14},md:{diameter:56,iconSize:22,fontSize:15,labelPaddingHorizontal:18},lg:{diameter:72,iconSize:28,fontSize:16,labelPaddingHorizontal:22}},toneBackground=(e,t)=>{switch(t){case"success":return e.colors.success;case"warning":return e.colors.warning;case"error":return e.colors.error;case"neutral":return e.colors.background.tertiary;default:return e.colors.primary}},pressedTintFor=(e,t)=>"neutral"===t?e.colors.surface.pressed:ACCENT_PRESSED_TINT,toneForeground=(e,t)=>{if("neutral"===t)return e.colors.text.primary;switch(t){case"success":return e.colors.onSuccess;case"warning":return e.colors.onWarning;case"error":return e.colors.onError;default:return e.colors.onPrimary}},FloatingActionButton=forwardRef((e,t)=>{const{icon:o,onPress:n,label:i,collapsed:s=!1,size:r="md",tone:a="primary",position:l,bottomOffset:c,disabled:u=!1,hideOnScroll:d=!1,isScrolling:m=!1,accessibilityLabel:g,accessibilityHint:b,haptic:p,style:f,containerStyle:h,labelStyle:y,testID:S}=e,x=useTheme(),R=useSafeAreaInsets(),w=sizeMap[r],A=useMemo(()=>buildStyles(x),[x]),{scale:v,pressIn:_,pressOut:C}=usePressAnimation({enabled:!u}),E=x.components.floatingActionButton,j=E?.edgeOffset??24,I=E?.bottomOffset??24,P=useRef(createAnimatedValue(0)).current;useEffect(()=>{if(!d)return void setNativeValue(P,0);const e=Animated.timing(P,{toValue:m?1:0,duration:x.motion.duration.normal,easing:Easing.bezier(...x.motion.easing.standard),useNativeDriver:!0});return e.start(),()=>e.stop()},[d,m,P,x.motion.duration.normal,x.motion.easing.standard]);const V=P.interpolate({inputRange:[0,1],outputRange:[0,w.diameter+(c??I)+R.bottom+j]}),k=P.interpolate({inputRange:[0,1],outputRange:[1,0]}),F=o,T="string"==typeof i&&i.length>0,z=T&&s,D=useReducedMotion(),M=x.spacing.sm,O=w.labelPaddingHorizontal,B=x.motion.duration.fast,N=x.motion.easing.standard,H=useSharedValue(z?1:0),[L,$]=useState(null);useEffect(()=>{const e=z?1:0;return H.value=D?e:withTiming(e,{duration:B,easing:ReanimatedEasing.bezier(...N)}),()=>cancelAnimation(H)},[z,D,H,B,N]);const G=useCallback(e=>{const t=Math.ceil(e);$(e=>e===t?e:t)},[]),W=useAnimatedStyle(()=>({paddingHorizontal:O*(1-H.value)})),U=useAnimatedStyle(()=>{const e=Math.max(0,1-2*H.value);return null===L?H.value>=1?{opacity:e,width:0}:{opacity:e}:{opacity:e,width:(L+M)*(1-H.value)}}),Y=u?x.colors.surface.disabled:toneBackground(x,a),Q=u?x.colors.text.disabled:toneForeground(x,a),X=useMemo(()=>{if(!l)return null;const e=(c??I)+R.bottom;switch(l){case"bottomLeft":return{position:"absolute",bottom:e,left:j};case"bottomCenter":return{position:"absolute",bottom:e,alignSelf:"center"};default:return{position:"absolute",bottom:e,right:j}}},[l,c,R.bottom,I,j]);return _jsx(Animated.View,{style:[X,{transform:[{translateY:V},{scale:v}],opacity:k},h,f],pointerEvents:d&&m?"none":"auto",children:_jsx(Pressable,{ref:t,onPress:e=>{if(u)return;const t=resolveHaptic(p,"impactLight");t&&triggerHaptic(t),n()},onPressIn:_,onPressOut:C,disabled:u,accessibilityRole:"button",accessibilityLabel:g,accessibilityHint:b,accessibilityState:{disabled:u},"aria-disabled":u,testID:S,style:[A.base,T?{height:w.diameter,minWidth:w.diameter,borderRadius:w.diameter/2,...smoothCorners}:{width:w.diameter,height:w.diameter,borderRadius:w.diameter/2,...smoothCorners},x.shadows.lg,{backgroundColor:Y,opacity:u?.55:1}],children:({pressed:e})=>_jsxs(_Fragment,{children:[e&&!u?_jsx(View,{pointerEvents:"none",testID:"fab-pressed",style:[A.pressedTint,{backgroundColor:pressedTintFor(x,a),borderRadius:w.diameter/2,...smoothCorners}]}):null,T?_jsxs(Reanimated.View,{style:[A.extendedRow,W],children:[F,_jsx(Reanimated.View,{style:[A.labelClip,U],children:_jsx(Text,{onLayout:e=>G(e.nativeEvent.layout.width),style:[A.label,{color:Q,fontSize:w.fontSize,fontWeight:x.typography.fontWeight.semibold,marginLeft:M},y],numberOfLines:1,children:i})})]}):F]})})})});FloatingActionButton.displayName="FloatingActionButton";const buildStyles=e=>StyleSheet.create({base:{flexDirection:"row",alignItems:"center",justifyContent:"center",overflow:"hidden"},pressedTint:{position:"absolute",top:0,right:0,bottom:0,left:0},extendedRow:{flexDirection:"row",alignItems:"center"},labelClip:{flexDirection:"row",overflow:"hidden"},label:{includeFontPadding:!1,flexShrink:0}}),FAB_GROUP_MIN_ACTIONS=2,FAB_GROUP_MAX_ACTIONS=6,FAB_GROUP_RANGE="2 to 6",describeActionProblem=e=>e.length<2?`was given ${e.length} action(s); a menu holds 2 to 6.`:e.length>6?`was given ${e.length} actions; a menu holds 2 to 6, so only the first 6 are drawn.`:e.some(e=>"string"!=typeof e.label||""===e.label.trim())?"has an action without a visible `label`; every menu action needs one.":"",FloatingActionButtonGroup=e=>{const{primaryIcon:t,primaryActiveIcon:o,actions:n,open:i,defaultOpen:s=!1,onOpenChange:r,position:a="bottomRight",bottomOffset:l,size:c="md",accessibilityLabel:u="Quick actions",haptic:d,hideOnScroll:m=!1,isScrolling:g=!1,containerStyle:b,secondaryActionStyle:p,labelPillStyle:f,labelStyle:h,testID:y}=e,S=useTheme(),x=useSafeAreaInsets(),R=sizeMap[c],w=useMemo(()=>buildGroupStyles(S),[S]),A=S.components.floatingActionButton,v=A?.edgeOffset??24,_=A?.bottomOffset??24,C=A?.secondaryGap??16,E=A?.staggerMs??50,j=useMemo(()=>n.slice(0,6),[n]),I=j.length,P=useMemo(()=>j.map((e,t)=>({action:e,index:t})).reverse(),[j]),V=__DEV__?describeActionProblem(n):"";useEffect(()=>{__DEV__&&V&&console.warn(`[@webority/mobile-ui] FloatingActionButtonGroup ${V}`)},[V]);const k="boolean"==typeof i,[F,T]=useState(s),z=k?i:F,D=useRef(createAnimatedValue(0)).current;useEffect(()=>{if(!m)return void setNativeValue(D,0);const e=Animated.timing(D,{toValue:g?1:0,duration:S.motion.duration.normal,easing:Easing.bezier(...S.motion.easing.standard),useNativeDriver:!0});return e.start(),()=>e.stop()},[m,g,D,S.motion.duration.normal,S.motion.easing.standard]);const M=m&&g;useEffect(()=>{M&&z&&(k||T(!1),r?.(!1))},[M,z,k,r]);const O=D.interpolate({inputRange:[0,1],outputRange:[0,R.diameter+(l??_)+x.bottom+v]}),B=D.interpolate({inputRange:[0,1],outputRange:[1,0]}),N=useRef(createAnimatedValue(z?1:0)).current,H=useRef([]),[L,$]=useState(0);useEffect(()=>{const e=H.current;if(e.length!==I){if(e.length<I){const t=e.slice();for(let o=e.length;o<I;o+=1)t.push(new Animated.Value(z?1:0));H.current=t}else H.current=e.slice(0,I);$(e=>e+1)}},[I]),useEffect(()=>{const e=Animated.timing(N,{toValue:z?1:0,duration:S.motion.duration.normal,easing:Easing.bezier(...S.motion.easing.standard),useNativeDriver:!0});e.start();const t=H.current.map(e=>Animated.timing(e,{toValue:z?1:0,duration:S.motion.duration.normal,easing:Easing.bezier(...S.motion.easing.standard),useNativeDriver:!0})),o=z?t:[...t].reverse(),n=Animated.stagger(E,o);return n.start(),()=>{e.stop(),n.stop()}},[z,N,S.motion.duration.normal,S.motion.easing.standard,I,L,E]);const G=useCallback(e=>{const t=resolveHaptic(d,"impactLight");t&&triggerHaptic(t),k||T(e),r?.(e)},[k,r,d]),W=useRef(null),U=useRef(z),Y=useRef(!1);useEffect(()=>{if(U.current===z)return;U.current=z;const e=Y.current;if(Y.current=!1,M||e)return;const t=W.current;t&&("web"===Platform.OS?t.focus?.():AccessibilityInfo.sendAccessibilityEvent(t,"focus"));announce(z?`${u}, expanded, ${I} ${1===I?"action":"actions"}`:`${u}, collapsed`)},[z,M,u,I]);const Q=useCallback(()=>{G(!z)},[z,G]),X=useCallback(e=>{!1!==d&&triggerHaptic("selection"),Y.current=!0,e.onPress(),k||T(!1),r?.(!1)},[k,r,d]),q=useCallback(()=>{z&&G(!1)},[z,G]),J=useMemo(()=>{const e=(l??_)+x.bottom;switch(a){case"bottomLeft":return{position:"absolute",bottom:e,left:v,alignItems:"flex-start"};case"bottomCenter":return{position:"absolute",bottom:e,alignSelf:"center",alignItems:"center"};default:return{position:"absolute",bottom:e,right:v,alignItems:"flex-end"}}},[a,l,x.bottom,_,v]),slotOffset=e=>-(R.diameter+C)*(e+1),K=useMemo(()=>{switch(a){case"bottomLeft":return{left:0,right:0,justifyContent:"flex-start"};case"bottomCenter":return{left:0,right:0,justifyContent:"center"};default:return{left:0,right:0,justifyContent:"flex-end"}}},[a]),Z=.78*R.diameter,ee=useMemo(()=>{const e=Z+S.spacing.sm;switch(a){case"bottomLeft":return{left:e,alignItems:"flex-start"};case"bottomCenter":return{right:R.diameter/2+Z/2+S.spacing.sm,alignItems:"flex-end"};default:return{right:e,alignItems:"flex-end"}}},[a,Z,R.diameter,S.spacing.sm]),te=N.interpolate({inputRange:[0,1],outputRange:[0,.4]}),oe=N.interpolate({inputRange:[0,1],outputRange:["0deg","45deg"]});return _jsxs(_Fragment,{children:[z?_jsx(Animated.View,{pointerEvents:z?"auto":"none",style:[StyleSheet.absoluteFill,{backgroundColor:S.colors.background.overlay,opacity:te}],children:_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:q,accessibilityElementsHidden:!0,importantForAccessibility:"no",testID:y?`${y}-backdrop`:void 0})}):null,_jsxs(Animated.View,{pointerEvents:M?"none":"box-none",style:[J,{transform:[{translateY:O}],opacity:B},b],accessibilityRole:"menu",testID:y,children:[P.map(({action:e,index:t})=>{const o=H.current[t];if(!o)return null;const n=o.interpolate({inputRange:[0,1],outputRange:[0,slotOffset(t)]}),i=o.interpolate({inputRange:[0,1],outputRange:[.6,1]}),s=toneBackground(S,e.tone??"primary"),r=toneForeground(S,e.tone??"primary"),a=e.label?_jsx(View,{pointerEvents:"none",style:[w.labelSlot,ee],testID:y?`${y}-label-${e.key}`:void 0,children:_jsx(View,{style:[w.labelPill,S.shadows.sm,{backgroundColor:S.colors.background.elevated,paddingHorizontal:S.spacing.sm,paddingVertical:S.spacing.xs,borderRadius:S.radius.sm,...smoothCorners},f],children:_jsx(Text,{style:[{color:S.colors.text.primary,fontSize:S.typography.fontSize.sm,fontWeight:S.typography.fontWeight.medium},h],numberOfLines:1,children:e.label})})}):null;return _jsxs(Animated.View,{pointerEvents:z?"auto":"none",accessibilityElementsHidden:!z,importantForAccessibility:z?"auto":"no-hide-descendants","aria-hidden":!z,style:[w.secondaryRow,K,{position:"absolute",bottom:0,opacity:o,transform:[{translateY:n},{scale:i}]}],children:[_jsx(Pressable,{onPress:()=>X(e),focusable:z,accessibilityRole:"menuitem",accessibilityLabel:e.accessibilityLabel,style:[w.fabBase,S.shadows.md,{width:Z,height:Z,borderRadius:Z/2,...smoothCorners,backgroundColor:s},p],testID:y?`${y}-action-${e.key}`:void 0,children:({pressed:t})=>_jsxs(_Fragment,{children:[t?_jsx(View,{pointerEvents:"none",testID:"fab-pressed",style:[w.pressedTint,{backgroundColor:pressedTintFor(S,e.tone??"primary"),borderRadius:Z/2,...smoothCorners}]}):null,React.isValidElement(e.icon)?e.icon:_jsx(Text,{style:{color:r},children:String(e.icon??"")})]})}),a]},e.key)}),_jsx(Pressable,{ref:W,onPress:Q,accessibilityRole:"button",accessibilityLabel:u,accessibilityState:{expanded:z},"aria-expanded":z,style:[w.fabBase,S.shadows.lg,{width:R.diameter,height:R.diameter,borderRadius:R.diameter/2,...smoothCorners,backgroundColor:S.colors.primary}],testID:y?`${y}-primary`:void 0,children:({pressed:e})=>_jsxs(_Fragment,{children:[e?_jsx(View,{pointerEvents:"none",testID:"fab-pressed",style:[w.pressedTint,{backgroundColor:ACCENT_PRESSED_TINT,borderRadius:R.diameter/2,...smoothCorners}]}):null,_jsx(Animated.View,{style:o?void 0:{transform:[{rotate:oe}]},children:z&&o?o:t})]})})]})]})},buildGroupStyles=e=>StyleSheet.create({fabBase:{flexDirection:"row",alignItems:"center",justifyContent:"center",overflow:"hidden"},pressedTint:{position:"absolute",top:0,right:0,bottom:0,left:0},secondaryRow:{flexDirection:"row",alignItems:"center"},labelSlot:{position:"absolute",top:0,bottom:0,justifyContent:"center"},labelPill:{alignSelf:"auto"}});export{FloatingActionButton,FloatingActionButtonGroup};export default FloatingActionButton;
1
+ "use strict";import React,{forwardRef,useCallback,useEffect,useMemo,useRef,useState}from"react";import{AccessibilityInfo,Animated,BackHandler,Easing,Platform,Pressable,StyleSheet,Text,View}from"react-native";import Reanimated,{cancelAnimation,Easing as ReanimatedEasing,useAnimatedStyle,useSharedValue,withTiming}from"react-native-reanimated";import{useSafeAreaInsets}from"react-native-safe-area-context";import{usePresenceMotion}from"../../hooks/usePresenceMotion.js";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{createAnimatedValue,setNativeValue,useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{ACCENT_PRESSED_TINT}from"../../utils/color.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const sizeMap={sm:{diameter:40,iconSize:18,fontSize:13,labelPaddingHorizontal:14},md:{diameter:56,iconSize:22,fontSize:15,labelPaddingHorizontal:18},lg:{diameter:72,iconSize:28,fontSize:16,labelPaddingHorizontal:22}},toneBackground=(e,t)=>{switch(t){case"success":return e.colors.success;case"warning":return e.colors.warning;case"error":return e.colors.error;case"neutral":return e.colors.background.tertiary;default:return e.colors.primary}},pressedTintFor=(e,t)=>"neutral"===t?e.colors.surface.pressed:ACCENT_PRESSED_TINT,toneForeground=(e,t)=>{if("neutral"===t)return e.colors.text.primary;switch(t){case"success":return e.colors.onSuccess;case"warning":return e.colors.onWarning;case"error":return e.colors.onError;default:return e.colors.onPrimary}},FloatingActionButton=forwardRef((e,t)=>{const{icon:n,onPress:o,label:s,collapsed:i=!1,size:r="md",tone:a="primary",position:l,bottomOffset:c,disabled:u=!1,hideOnScroll:d=!1,isScrolling:m=!1,accessibilityLabel:g,accessibilityHint:f,haptic:b,style:p,containerStyle:h,labelStyle:y,testID:S}=e,w=useTheme(),x=useSafeAreaInsets(),v=sizeMap[r],A=useMemo(()=>buildStyles(w),[w]),{scale:R,opacity:_,pressIn:E,pressOut:C}=usePressAnimation({enabled:!u}),j=usePresenceMotion(),P=w.components.floatingActionButton,I=P?.edgeOffset??24,k=P?.bottomOffset??24,V=useRef(createAnimatedValue(1)).current,F=j.duration("normal");useEffect(()=>{if(!d)return void setNativeValue(V,1);const e=Animated.timing(V,{toValue:m?0:1,duration:F,easing:Easing.bezier(...w.motion.easing.standard),useNativeDriver:!0});return e.start(),()=>e.stop()},[d,m,V,F,w.motion.easing.standard]);const T=v.diameter+(c??k)+x.bottom+I,z=V.interpolate({inputRange:[0,1],outputRange:j.range(T,0)}),D=useMemo(()=>Animated.multiply(V,_),[V,_]),B=n,M="string"==typeof s&&s.length>0,O=M&&i,H=j.reduced,L=w.spacing.sm,N=v.labelPaddingHorizontal,$=w.motion.duration.fast,G=w.motion.easing.standard,W=useSharedValue(O?1:0),[U,Y]=useState(null);useEffect(()=>{const e=O?1:0;return W.value=H?e:withTiming(e,{duration:$,easing:ReanimatedEasing.bezier(...G)}),()=>cancelAnimation(W)},[O,H,W,$,G]);const Q=useCallback(e=>{const t=Math.ceil(e);Y(e=>e===t?e:t)},[]),X=useAnimatedStyle(()=>({paddingHorizontal:N*(1-W.value)})),q=useAnimatedStyle(()=>{const e=Math.max(0,1-2*W.value);return null===U?W.value>=1?{opacity:e,width:0}:{opacity:e}:{opacity:e,width:(U+L)*(1-W.value)}}),J=u?w.colors.surface.disabled:toneBackground(w,a),K=u?w.colors.text.disabled:toneForeground(w,a),Z=useMemo(()=>{if(!l)return null;const e=(c??k)+x.bottom;switch(l){case"bottomLeft":return{position:"absolute",bottom:e,left:I};case"bottomCenter":return{position:"absolute",bottom:e,alignSelf:"center"};default:return{position:"absolute",bottom:e,right:I}}},[l,c,x.bottom,k,I]);return _jsx(Animated.View,{style:[Z,{transform:[{translateY:z},{scale:R}],opacity:D},h,p],pointerEvents:d&&m?"none":"auto",children:_jsx(Pressable,{ref:t,onPress:e=>{if(u)return;const t=resolveHaptic(b,"impactLight");t&&triggerHaptic(t),o()},onPressIn:E,onPressOut:C,disabled:u,accessibilityRole:"button",accessibilityLabel:g,accessibilityHint:f,accessibilityState:{disabled:u},"aria-disabled":u,testID:S,style:[A.base,M?{height:v.diameter,minWidth:v.diameter,borderRadius:v.diameter/2,...smoothCorners}:{width:v.diameter,height:v.diameter,borderRadius:v.diameter/2,...smoothCorners},w.shadows.lg,{backgroundColor:J,opacity:u?.55:1}],children:({pressed:e})=>_jsxs(_Fragment,{children:[e&&!u?_jsx(View,{pointerEvents:"none",testID:"fab-pressed",style:[A.pressedTint,{backgroundColor:pressedTintFor(w,a),borderRadius:v.diameter/2,...smoothCorners}]}):null,M?_jsxs(Reanimated.View,{style:[A.extendedRow,X],children:[B,_jsx(Reanimated.View,{style:[A.labelClip,q],children:_jsx(Text,{onLayout:e=>Q(e.nativeEvent.layout.width),style:[A.label,{color:K,fontSize:v.fontSize,fontWeight:w.typography.fontWeight.semibold,marginLeft:L},y],numberOfLines:1,children:s})})]}):B]})})})});FloatingActionButton.displayName="FloatingActionButton";const buildStyles=e=>StyleSheet.create({base:{flexDirection:"row",alignItems:"center",justifyContent:"center",overflow:"hidden"},pressedTint:{position:"absolute",top:0,right:0,bottom:0,left:0},extendedRow:{flexDirection:"row",alignItems:"center"},labelClip:{flexDirection:"row",overflow:"hidden"},label:{includeFontPadding:!1,flexShrink:0}}),FAB_GROUP_MIN_ACTIONS=2,FAB_GROUP_MAX_ACTIONS=6,FAB_GROUP_RANGE="2 to 6",describeActionProblem=e=>e.length<2?`was given ${e.length} action(s); a menu holds 2 to 6.`:e.length>6?`was given ${e.length} actions; a menu holds 2 to 6, so only the first 6 are drawn.`:e.some(e=>"string"!=typeof e.label||""===e.label.trim())?"has an action without a visible `label`; every menu action needs one.":"",FloatingActionButtonGroup=e=>{const{primaryIcon:t,primaryActiveIcon:n,actions:o,open:s,defaultOpen:i=!1,onOpenChange:r,position:a="bottomRight",bottomOffset:l,size:c="md",accessibilityLabel:u="Quick actions",haptic:d,hideOnScroll:m=!1,isScrolling:g=!1,containerStyle:f,secondaryActionStyle:b,labelPillStyle:p,labelStyle:h,testID:y}=e,S=useTheme(),w=useSafeAreaInsets(),x=sizeMap[c],v=useMemo(()=>buildGroupStyles(S),[S]),A=usePresenceMotion(),R=A.duration("normal"),_=S.components.floatingActionButton,E=_?.edgeOffset??24,C=_?.bottomOffset??24,j=_?.secondaryGap??16,P=_?.staggerMs??50,I=useMemo(()=>o.slice(0,6),[o]),k=I.length,V=useMemo(()=>I.map((e,t)=>({action:e,index:t})).reverse(),[I]),F=__DEV__?describeActionProblem(o):"";useEffect(()=>{__DEV__&&F&&console.warn(`[@webority/mobile-ui] FloatingActionButtonGroup ${F}`)},[F]);const T="boolean"==typeof s,[z,D]=useState(i),B=T?s:z,M=useRef(createAnimatedValue(1)).current;useEffect(()=>{if(!m)return void setNativeValue(M,1);const e=Animated.timing(M,{toValue:g?0:1,duration:R,easing:Easing.bezier(...S.motion.easing.standard),useNativeDriver:!0});return e.start(),()=>e.stop()},[m,g,M,R,S.motion.easing.standard]);const O=m&&g;useEffect(()=>{O&&B&&(T||D(!1),r?.(!1))},[O,B,T,r]);const H=x.diameter+(l??C)+w.bottom+E,L=M.interpolate({inputRange:[0,1],outputRange:A.range(H,0)}),N=M,$=useRef(createAnimatedValue(B?1:0)).current,G=useRef([]),[W,U]=useState(0);useEffect(()=>{const e=G.current;if(e.length!==k){if(e.length<k){const t=e.slice();for(let n=e.length;n<k;n+=1)t.push(new Animated.Value(B?1:0));G.current=t}else G.current=e.slice(0,k);U(e=>e+1)}},[k]),useEffect(()=>{const e=Animated.timing($,{toValue:B?1:0,duration:R,easing:Easing.bezier(...S.motion.easing.standard),useNativeDriver:!0});e.start();const t=G.current.map(e=>Animated.timing(e,{toValue:B?1:0,duration:R,easing:Easing.bezier(...S.motion.easing.standard),useNativeDriver:!0})),n=B?t:[...t].reverse(),o=Animated.stagger(P,n);return o.start(),()=>{e.stop(),o.stop()}},[B,$,R,S.motion.easing.standard,k,W,P]);const Y=useCallback(e=>{const t=resolveHaptic(d,"impactLight");t&&triggerHaptic(t),T||D(e),r?.(e)},[T,r,d]),Q=useRef(null),X=useRef(B),q=useRef(!1);useEffect(()=>{if(X.current===B)return;X.current=B;const e=q.current;if(q.current=!1,O||e)return;const t=Q.current;t&&("web"===Platform.OS?t.focus?.():AccessibilityInfo.sendAccessibilityEvent(t,"focus"));announce(B?`${u}, expanded, ${k} ${1===k?"action":"actions"}`:`${u}, collapsed`)},[B,O,u,k]);const J=useCallback(()=>{Y(!B)},[B,Y]),K=useCallback(e=>{!1!==d&&triggerHaptic("selection"),q.current=!0,e.onPress(),T||D(!1),r?.(!1)},[T,r,d]),Z=useCallback(()=>{B&&Y(!1)},[B,Y]);useEffect(()=>{if(!B)return;const e=BackHandler.addEventListener("hardwareBackPress",()=>(Y(!1),!0));return()=>e.remove()},[B,Y]),useEffect(()=>{if(!B||"web"!==Platform.OS)return;const onKeyDown=e=>{"Escape"===e.key&&Y(!1)};return window.addEventListener("keydown",onKeyDown),()=>window.removeEventListener("keydown",onKeyDown)},[B,Y]);const ee=useMemo(()=>{const e=(l??C)+w.bottom;switch(a){case"bottomLeft":return{position:"absolute",bottom:e,left:E,alignItems:"flex-start"};case"bottomCenter":return{position:"absolute",bottom:e,alignSelf:"center",alignItems:"center"};default:return{position:"absolute",bottom:e,right:E,alignItems:"flex-end"}}},[a,l,w.bottom,C,E]),slotOffset=e=>-(x.diameter+j)*(e+1),te=useMemo(()=>{switch(a){case"bottomLeft":return{left:0,right:0,justifyContent:"flex-start"};case"bottomCenter":return{left:0,right:0,justifyContent:"center"};default:return{left:0,right:0,justifyContent:"flex-end"}}},[a]),ne=.78*x.diameter,oe=useMemo(()=>{const e=ne+S.spacing.sm;switch(a){case"bottomLeft":return{left:e,alignItems:"flex-start"};case"bottomCenter":return{right:x.diameter/2+ne/2+S.spacing.sm,alignItems:"flex-end"};default:return{right:e,alignItems:"flex-end"}}},[a,ne,x.diameter,S.spacing.sm]),se=$.interpolate({inputRange:[0,1],outputRange:[0,.4]}),ie=$.interpolate(A.reduced?{inputRange:[0,.5,.5001,1],outputRange:["0deg","0deg","45deg","45deg"]}:{inputRange:[0,1],outputRange:["0deg","45deg"]});return _jsxs(_Fragment,{children:[B?_jsx(Animated.View,{pointerEvents:B?"auto":"none",style:[StyleSheet.absoluteFill,{backgroundColor:S.colors.background.overlay,opacity:se}],children:_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:Z,accessibilityElementsHidden:!0,importantForAccessibility:"no",testID:y?`${y}-backdrop`:void 0})}):null,_jsxs(Animated.View,{pointerEvents:O?"none":"box-none",style:[ee,{transform:[{translateY:L}],opacity:N},f],accessibilityRole:"menu",testID:y,children:[V.map(({action:e,index:t})=>{const n=G.current[t];if(!n)return null;const o=n.interpolate({inputRange:[0,1],outputRange:A.range(0,slotOffset(t))}),s=n.interpolate({inputRange:[0,1],outputRange:A.range(.6,1)}),i=toneBackground(S,e.tone??"primary"),r=toneForeground(S,e.tone??"primary"),a=e.label?_jsx(View,{pointerEvents:"none",style:[v.labelSlot,oe],testID:y?`${y}-label-${e.key}`:void 0,children:_jsx(View,{style:[v.labelPill,S.shadows.sm,{backgroundColor:S.colors.background.elevated,paddingHorizontal:S.spacing.sm,paddingVertical:S.spacing.xs,borderRadius:S.radius.sm,...smoothCorners},p],children:_jsx(Text,{style:[{color:S.colors.text.primary,fontSize:S.typography.fontSize.sm,fontWeight:S.typography.fontWeight.medium},h],numberOfLines:1,children:e.label})})}):null;return _jsxs(Animated.View,{pointerEvents:B?"auto":"none",accessibilityElementsHidden:!B,importantForAccessibility:B?"auto":"no-hide-descendants","aria-hidden":!B,style:[v.secondaryRow,te,{position:"absolute",bottom:0,opacity:n,transform:[{translateY:o},{scale:s}]}],children:[_jsx(Pressable,{onPress:()=>K(e),focusable:B,accessibilityRole:"menuitem",accessibilityLabel:e.accessibilityLabel,style:[v.fabBase,S.shadows.md,{width:ne,height:ne,borderRadius:ne/2,...smoothCorners,backgroundColor:i},b],testID:y?`${y}-action-${e.key}`:void 0,children:({pressed:t})=>_jsxs(_Fragment,{children:[t?_jsx(View,{pointerEvents:"none",testID:"fab-pressed",style:[v.pressedTint,{backgroundColor:pressedTintFor(S,e.tone??"primary"),borderRadius:ne/2,...smoothCorners}]}):null,React.isValidElement(e.icon)?e.icon:_jsx(Text,{style:{color:r},children:String(e.icon??"")})]})}),a]},e.key)}),_jsx(Pressable,{ref:Q,onPress:J,accessibilityRole:"button",accessibilityLabel:u,accessibilityState:{expanded:B},"aria-expanded":B,style:[v.fabBase,S.shadows.lg,{width:x.diameter,height:x.diameter,borderRadius:x.diameter/2,...smoothCorners,backgroundColor:S.colors.primary}],testID:y?`${y}-primary`:void 0,children:({pressed:e})=>_jsxs(_Fragment,{children:[e?_jsx(View,{pointerEvents:"none",testID:"fab-pressed",style:[v.pressedTint,{backgroundColor:ACCENT_PRESSED_TINT,borderRadius:x.diameter/2,...smoothCorners}]}):null,_jsx(Animated.View,{style:n?void 0:{transform:[{rotate:ie}]},children:B&&n?n:t})]})})]})]})},buildGroupStyles=e=>StyleSheet.create({fabBase:{flexDirection:"row",alignItems:"center",justifyContent:"center",overflow:"hidden"},pressedTint:{position:"absolute",top:0,right:0,bottom:0,left:0},secondaryRow:{flexDirection:"row",alignItems:"center"},labelSlot:{position:"absolute",top:0,bottom:0,justifyContent:"center"},labelPill:{alignSelf:"auto"}});export{FloatingActionButton,FloatingActionButtonGroup};export default FloatingActionButton;
@@ -1 +1 @@
1
- "use strict";import{forwardRef}from"react";import{Animated,Pressable,StyleSheet}from"react-native";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{useTheme}from"../../theme/index.js";import{resolveHaptic,triggerHaptic}from"../../utils/index.js";import{tintOf}from"../../utils/color.js";import{smoothCorners}from"../../utils/corners.js";import{renderSlotIcon}from"../AppIcon/slotIcon.js";import{Spinner}from"../Spinner/index.js";import{jsx as _jsx}from"react/jsx-runtime";const GLASS_RIM_WIDTH=1,SOFT_FILL_OPACITY=.14,SIZE_MAP={sm:{diameter:32,icon:16},md:{diameter:40,icon:20},lg:{diameter:48,icon:24}},toneFor=(e,r)=>{switch(r){case"secondary":return{base:e.colors.secondary,on:e.colors.onSecondary,fg:e.colors.secondary};case"success":return{base:e.colors.success,on:e.colors.onSuccess,fg:e.colors.toneText.success};case"warning":return{base:e.colors.warning,on:e.colors.onWarning,fg:e.colors.toneText.warning};case"error":return{base:e.colors.error,on:e.colors.onError,fg:e.colors.toneText.error};case"neutral":return{base:e.colors.background.tertiary,on:e.colors.text.primary,fg:e.colors.text.primary};default:return{base:e.colors.primary,on:e.colors.onPrimary,fg:e.colors.primary}}},IconButton=forwardRef((e,r)=>{const{icon:o,iconVariant:s,onPress:t,accessibilityLabel:n,tone:i="primary",variant:c="solid",size:a="md",shape:l="circle",active:d=!1,disabled:m=!1,loading:u=!1,haptic:b,style:p,testID:f}=e,y=useTheme(),g=SIZE_MAP[a],I=m||u,{scale:h,pressIn:x,pressOut:S}=usePressAnimation({scaleTo:.92,enabled:!I}),{base:j,on:P,fg:A}=toneFor(y,i),_=d?"solid":c;let w="transparent",T="transparent",C=0,O=I?y.colors.text.disabled:A;"solid"===_?(w=I?y.colors.surface.disabled:j,O=I?y.colors.text.disabled:P):"soft"===_?w=I?y.colors.surface.disabled:tintOf(j,.14,y.colors.background.secondary):"outline"===_?(T=I?y.colors.border.primary:j,C=y.colors.border.width):"glass"===_&&(w=y.colors.glass.fill,T=y.colors.glass.border,C=1,O=I?y.colors.text.disabled:y.colors.glass.on);const v={color:O,size:g.icon,disabled:I},B="circle"===l?g.diameter/2:y.radius.md;return _jsx(Pressable,{ref:r,onPress:e=>{if(I)return;const r=resolveHaptic(b,"selection");r&&triggerHaptic(r),t?.(e)},onPressIn:x,onPressOut:S,disabled:I,accessibilityRole:"button",accessibilityLabel:n,accessibilityState:{disabled:I,selected:d},"aria-disabled":I,"aria-selected":d,hitSlop:6,testID:f,style:({pressed:e})=>[styles.base,{width:g.diameter,height:g.diameter,borderRadius:B,...smoothCorners,backgroundColor:w,borderColor:T,borderWidth:C,opacity:e&&"solid"!==_?.7:1},p],children:_jsx(Animated.View,{style:[styles.content,{transform:[{scale:h}]}],children:u?_jsx(Spinner,{size:"sm",color:O}):renderSlotIcon(o,v,s)})})});IconButton.displayName="IconButton";const styles=StyleSheet.create({base:{alignItems:"center",justifyContent:"center"},content:{alignItems:"center",justifyContent:"center"}});export{IconButton};export default IconButton;
1
+ "use strict";import{forwardRef}from"react";import{Animated,Pressable,StyleSheet}from"react-native";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{useTheme}from"../../theme/index.js";import{resolveHaptic,triggerHaptic}from"../../utils/index.js";import{tintOf}from"../../utils/color.js";import{smoothCorners}from"../../utils/corners.js";import{renderSlotIcon}from"../AppIcon/slotIcon.js";import{Spinner}from"../Spinner/index.js";import{jsx as _jsx}from"react/jsx-runtime";const GLASS_RIM_WIDTH=1,SOFT_FILL_OPACITY=.14,SIZE_MAP={sm:{diameter:32,icon:16},md:{diameter:40,icon:20},lg:{diameter:48,icon:24}},toneFor=(e,o)=>{switch(o){case"secondary":return{base:e.colors.secondary,on:e.colors.onSecondary,fg:e.colors.secondary};case"success":return{base:e.colors.success,on:e.colors.onSuccess,fg:e.colors.toneText.success};case"warning":return{base:e.colors.warning,on:e.colors.onWarning,fg:e.colors.toneText.warning};case"error":return{base:e.colors.error,on:e.colors.onError,fg:e.colors.toneText.error};case"neutral":return{base:e.colors.background.tertiary,on:e.colors.text.primary,fg:e.colors.text.primary};default:return{base:e.colors.primary,on:e.colors.onPrimary,fg:e.colors.primary}}},IconButton=forwardRef((e,o)=>{const{icon:r,iconVariant:s,onPress:t,accessibilityLabel:n,tone:i="primary",variant:c="solid",size:a="md",shape:l="circle",active:d=!1,disabled:m=!1,loading:u=!1,haptic:b,style:p,testID:f}=e,y=useTheme(),g=SIZE_MAP[a],I=m||u,{style:h,pressIn:x,pressOut:S}=usePressAnimation({scaleTo:.92,enabled:!I}),{base:j,on:P,fg:A}=toneFor(y,i),_=d?"solid":c;let w="transparent",T="transparent",C=0,O=I?y.colors.text.disabled:A;"solid"===_?(w=I?y.colors.surface.disabled:j,O=I?y.colors.text.disabled:P):"soft"===_?w=I?y.colors.surface.disabled:tintOf(j,.14,y.colors.background.secondary):"outline"===_?(T=I?y.colors.border.primary:j,C=y.colors.border.width):"glass"===_&&(w=y.colors.glass.fill,T=y.colors.glass.border,C=1,O=I?y.colors.text.disabled:y.colors.glass.on);const v={color:O,size:g.icon,disabled:I},B="circle"===l?g.diameter/2:y.radius.md;return _jsx(Pressable,{ref:o,onPress:e=>{if(I)return;const o=resolveHaptic(b,"selection");o&&triggerHaptic(o),t?.(e)},onPressIn:x,onPressOut:S,disabled:I,accessibilityRole:"button",accessibilityLabel:n,accessibilityState:{disabled:I,selected:d},"aria-disabled":I,"aria-selected":d,hitSlop:6,testID:f,style:({pressed:e})=>[styles.base,{width:g.diameter,height:g.diameter,borderRadius:B,...smoothCorners,backgroundColor:w,borderColor:T,borderWidth:C,opacity:e&&"solid"!==_?.7:1},p],children:_jsx(Animated.View,{style:[styles.content,h],children:u?_jsx(Spinner,{size:"sm",color:O}):renderSlotIcon(r,v,s)})})});IconButton.displayName="IconButton";const styles=StyleSheet.create({base:{alignItems:"center",justifyContent:"center"},content:{alignItems:"center",justifyContent:"center"}});export{IconButton};export default IconButton;
@@ -1 +1 @@
1
- "use strict";import React,{forwardRef,useMemo}from"react";import{Animated,Pressable,StyleSheet,Text,useWindowDimensions,View}from"react-native";import Svg,{Path}from"react-native-svg";import{useFlickGuard}from"../../hooks/useFlickGuard.js";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{fontFor,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{mergeRefs}from"../../utils/mergeRefs.js";import{defaultIcons}from"../AppIcon/defaultIcons.js";import{Button}from"../Button/index.js";import{IconBadge}from"../IconBadge/index.js";import{useContextMenu}from"../Menu/useContextMenu.js";import{Skeleton}from"../Skeleton/index.js";import{Swipeable}from"../Swipeable/index.js";import{Fragment as _Fragment,jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const SIZE_FALLBACK={sm:{paddingVertical:"sm",titleFontSize:"sm",subtitleFontSize:"xs",minHeight:44},md:{paddingVertical:"md",titleFontSize:"base",subtitleFontSize:"sm",minHeight:56},lg:{paddingVertical:"lg",titleFontSize:"lg",subtitleFontSize:"sm",minHeight:72}},sizeFor=(e,t)=>{const i={...SIZE_FALLBACK[t],...e.components.listItem?.[t]??{}};return{paddingVertical:e.spacing[i.paddingVertical],titleSize:e.typography.fontSize[i.titleFontSize],subtitleSize:e.typography.fontSize[i.subtitleFontSize],minHeight:i.minHeight}},Chevron=({color:e})=>{const t=useTheme();return _jsx(_Fragment,{children:(t.icons?.chevronRight??defaultIcons.chevronRight)({size:20,color:e})})},BADGE_SIZE={sm:"sm",md:"md",lg:"lg"},RIGHT_BELOW_FONT_SCALE=1.2,DEFAULT_BOX_SIZE=20,SelectionBox=({checked:e,disabled:t})=>{const i=useTheme(),s=i.components.checkbox?.md?.boxSize??20,o=Math.round(.72*s);return _jsx(View,{accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",pointerEvents:"none",style:{width:s,height:s,alignItems:"center",justifyContent:"center",borderWidth:i.colors.border.width,borderRadius:i.radius.xs,...smoothCorners,borderColor:e?i.colors.primary:i.colors.border.primary,backgroundColor:e?i.colors.primary:t?i.colors.surface.disabled:"transparent"},children:e?_jsx(Svg,{width:o,height:o,viewBox:"0 0 24 24",children:_jsx(Path,{d:"M5 12.5l4.5 4.5L19 7.5",stroke:i.colors.onPrimary,strokeWidth:3,strokeLinecap:"round",strokeLinejoin:"round",fill:"none"})}):null})},isActionList=e=>Array.isArray(e)&&e.length>0&&e.every(e=>null!=e&&"object"==typeof e&&!React.isValidElement(e)&&"label"in e),renderActions=e=>isActionList(e)?e.map(e=>_jsx(Button,{size:"sm",variant:e.variant??"outline",tone:e.tone,leftIcon:e.icon,disabled:e.disabled,testID:e.testID,title:e.label,onPress:e.onPress},e.label)):e,ListItem=forwardRef((e,t)=>{const{title:i,loading:s=!1,subtitle:o,description:n,titleLines:r=1,subtitleLines:l=1,left:a,icon:c,iconTone:d="primary",right:m,rightPlacement:h="auto",selectable:u=!1,checked:g=!1,onCheckedChange:p,actions:x,onPress:b,haptic:f,selected:y=!1,disabled:S=!1,size:j="md",divider:_=!1,chevron:w=!1,leftActions:I,rightActions:L,contextMenu:v,accessibilityLabel:k,accessibilityHint:z,style:V,containerStyle:F,titleStyle:A,subtitleStyle:C,descriptionStyle:B,leftSlotStyle:H,rightSlotStyle:R,testID:D}=e,P=useTheme(),T=useMemo(()=>sizeFor(P,j),[P,j]),E=useMemo(()=>buildStyles(P),[P]),{fontScale:M}=useWindowDimensions(),W=!!m&&("below"===h||"auto"===h&&M>1.2),O=useContextMenu(S?void 0:v,{haptic:f,testID:D}),G=useMemo(()=>mergeRefs(t,O.hostRef),[t,O.hostRef]),Z=u||!!b,N=Z||O.enabled,K=N&&!S,{scale:U,pressIn:X,pressOut:q}=usePressAnimation({enabled:K}),J=useFlickGuard(),Q=k??("string"==typeof i?i:void 0),isText=e=>"string"==typeof e||"number"==typeof e,Y=a??(void 0===c?null:_jsx(IconBadge,{icon:c,tone:d,size:BADGE_SIZE[j]})),$=u?_jsxs(View,{style:E.selectionLead,children:[_jsx(SelectionBox,{checked:g,disabled:S}),Y?_jsx(View,{style:E.selectionLeadContent,children:Y}):null]}):Y,ee=null!=x&&!1!==x&&!(Array.isArray(x)&&0===x.length),te=_&&!ee,ie=_jsxs(View,{style:[E.row,{paddingVertical:T.paddingVertical,minHeight:T.minHeight,backgroundColor:y?P.colors.surface.selected:"transparent"},te?E.divider:null,S?E.disabled:null,F],children:[$?_jsx(View,{style:[E.leftSlot,H],children:$}):null,_jsxs(View,{style:E.middle,children:[null==i||isText(i)?_jsx(Text,{style:[E.title,{fontSize:T.titleSize,...fontFor(P,"medium"),color:S?P.colors.text.disabled:P.colors.text.primary},A],numberOfLines:r,children:i??" "}):i,null==o||""===o?null:isText(o)?_jsx(Text,{style:[E.subtitle,{fontSize:T.subtitleSize,color:S?P.colors.text.disabled:P.colors.text.secondary},C],numberOfLines:l,children:o}):o,n?_jsx(Text,{style:[E.description,{fontSize:T.subtitleSize,color:S?P.colors.text.disabled:P.colors.text.tertiary},B],numberOfLines:2,children:n}):null,W?_jsx(View,{style:[E.rightBelow,R],children:m}):null]}),m&&!W||w?_jsxs(View,{style:[E.rightSlot,W?null:R],children:[W?null:m,w?_jsx(View,{style:m&&!W?E.chevronWithRight:null,children:_jsx(Chevron,{color:S?P.colors.text.disabled:P.colors.text.tertiary})}):null]}):null]}),se=N?_jsx(Animated.View,{style:[{transform:[{scale:U}]},V],children:_jsx(Pressable,{ref:G,onPress:e=>{if(!K||!Z||J.isFlick(e))return;const t=resolveHaptic(f,"selection");t&&triggerHaptic(t),u?p?.(!g):b?.(e)},onPressIn:e=>{J.onPressIn(e),X()},onPressOut:q,disabled:!K,accessibilityRole:u?"checkbox":b?"button":void 0,accessibilityLabel:Q,accessibilityHint:z,accessibilityState:u?{checked:g,disabled:!K}:{selected:y,disabled:!K},"aria-disabled":!K,...u?{"aria-checked":g}:{"aria-selected":y},testID:D,android_ripple:{color:P.colors.surface.pressed,borderless:!1},style:({pressed:e})=>e?E.pressed:null,...O.hostProps,children:ie})}):_jsx(View,{ref:t,accessibilityRole:"none",accessibilityLabel:Q,accessibilityHint:z,accessibilityState:{selected:y,disabled:S},"aria-selected":y,"aria-disabled":S,testID:D,style:V,children:ie}),oe=I&&I.length>0||L&&L.length>0,ne=ee?_jsxs(View,{style:[y?{backgroundColor:P.colors.surface.selected}:null,_?E.divider:null],children:[se,_jsx(View,{style:E.actions,children:renderActions(x)})]}):se,re=oe?_jsx(Swipeable,{leftActions:I,rightActions:L,accessibilityLabel:Q,children:ne}):ne;return s?_jsx(ListItemSkeleton,{...e}):O.enabled?_jsxs(_Fragment,{children:[re,O.renderSurface(_jsx(View,{style:E.preview,children:ie}))]}):re});ListItem.displayName="ListItem";const ListItemSkeleton=({subtitle:e,description:t,left:i,icon:s,right:o,chevron:n,size:r="md",containerStyle:l,style:a})=>{const c=useTheme(),d=sizeFor(c,r),m=Math.round(1.15*d.titleSize),h=Math.round(1.15*d.subtitleSize);return _jsxs(View,{style:[{flexDirection:"row",alignItems:"center",paddingHorizontal:c.spacing.md,paddingVertical:d.paddingVertical,minHeight:d.minHeight},l,a],children:[void 0!==i||void 0!==s?_jsx(View,{style:{marginRight:c.spacing.sm},children:_jsx(Skeleton,{shape:"circle",width:40,height:40})}):null,_jsxs(View,{style:{flex:1},children:[_jsx(Skeleton,{shape:"text",width:"70%",height:m,style:{marginBottom:c.spacing.xs}}),void 0!==e?_jsx(Skeleton,{shape:"text",width:"50%",height:h,style:void 0!==t?{marginBottom:c.spacing.xs}:void 0}):null,void 0!==t?_jsx(Skeleton,{shape:"text",width:"85%",height:h}):null]}),void 0!==o||n?_jsx(View,{style:{marginLeft:c.spacing.sm},children:_jsx(Skeleton,{width:20,height:20,radius:"sm"})}):null]})};ListItemSkeleton.displayName="ListItemSkeleton",ListItem.Skeleton=ListItemSkeleton;const buildStyles=e=>StyleSheet.create({row:{flexDirection:"row",alignItems:"center",paddingHorizontal:e.spacing.md},divider:{borderBottomWidth:StyleSheet.hairlineWidth,borderBottomColor:e.colors.border.primary},pressed:{backgroundColor:e.colors.surface.pressed},disabled:{opacity:.55},leftSlot:{marginRight:e.spacing.md,alignItems:"center",justifyContent:"center"},middle:{flex:1,flexDirection:"column",justifyContent:"center"},selectionLead:{flexDirection:"row",alignItems:"center"},selectionLeadContent:{marginLeft:e.spacing.sm},rightBelow:{alignSelf:"flex-start",flexDirection:"row",alignItems:"center",marginTop:e.spacing.xs},rightSlot:{marginLeft:e.spacing.md,alignItems:"center",justifyContent:"center",flexDirection:"row"},actions:{flexDirection:"row",flexWrap:"wrap",gap:e.spacing.sm,paddingHorizontal:e.spacing.md,paddingBottom:e.spacing.md},chevronWithRight:{marginLeft:e.spacing.xs},preview:{flex:1,backgroundColor:e.colors.background.elevated,borderRadius:e.radius.md,...smoothCorners,overflow:"hidden"},title:{letterSpacing:e.typography.letterSpacing.normal},subtitle:{marginTop:2,...fontFor(e,"normal")},description:{marginTop:2,...fontFor(e,"normal")}});export{ListItem};export default ListItem;
1
+ "use strict";import React,{forwardRef,useMemo}from"react";import{Animated,Pressable,StyleSheet,Text,useWindowDimensions,View}from"react-native";import Svg,{Path}from"react-native-svg";import{useFlickGuard}from"../../hooks/useFlickGuard.js";import{usePressAnimation}from"../../hooks/usePressAnimation.js";import{fontFor,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{triggerHaptic}from"../../utils/hapticUtils.js";import{mergeRefs}from"../../utils/mergeRefs.js";import{defaultIcons}from"../AppIcon/defaultIcons.js";import{Button}from"../Button/index.js";import{IconBadge}from"../IconBadge/index.js";import{useContextMenu}from"../Menu/useContextMenu.js";import{Skeleton}from"../Skeleton/index.js";import{Swipeable}from"../Swipeable/index.js";import{Fragment as _Fragment,jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const SIZE_FALLBACK={sm:{paddingVertical:"sm",titleFontSize:"sm",subtitleFontSize:"xs",minHeight:44},md:{paddingVertical:"md",titleFontSize:"base",subtitleFontSize:"sm",minHeight:56},lg:{paddingVertical:"lg",titleFontSize:"lg",subtitleFontSize:"sm",minHeight:72}},sizeFor=(e,t)=>{const i={...SIZE_FALLBACK[t],...e.components.listItem?.[t]??{}};return{paddingVertical:e.spacing[i.paddingVertical],titleSize:e.typography.fontSize[i.titleFontSize],subtitleSize:e.typography.fontSize[i.subtitleFontSize],minHeight:i.minHeight}},Chevron=({color:e})=>{const t=useTheme();return _jsx(_Fragment,{children:(t.icons?.chevronRight??defaultIcons.chevronRight)({size:20,color:e})})},BADGE_SIZE={sm:"sm",md:"md",lg:"lg"},RIGHT_BELOW_FONT_SCALE=1.2,DEFAULT_BOX_SIZE=20,SelectionBox=({checked:e,disabled:t})=>{const i=useTheme(),s=i.components.checkbox?.md?.boxSize??20,o=Math.round(.72*s);return _jsx(View,{accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",pointerEvents:"none",style:{width:s,height:s,alignItems:"center",justifyContent:"center",borderWidth:i.colors.border.width,borderRadius:i.radius.xs,...smoothCorners,borderColor:e?i.colors.primary:i.colors.border.primary,backgroundColor:e?i.colors.primary:t?i.colors.surface.disabled:"transparent"},children:e?_jsx(Svg,{width:o,height:o,viewBox:"0 0 24 24",children:_jsx(Path,{d:"M5 12.5l4.5 4.5L19 7.5",stroke:i.colors.onPrimary,strokeWidth:3,strokeLinecap:"round",strokeLinejoin:"round",fill:"none"})}):null})},isActionList=e=>Array.isArray(e)&&e.length>0&&e.every(e=>null!=e&&"object"==typeof e&&!React.isValidElement(e)&&"label"in e),renderActions=e=>isActionList(e)?e.map(e=>_jsx(Button,{size:"sm",variant:e.variant??"outline",tone:e.tone,leftIcon:e.icon,disabled:e.disabled,testID:e.testID,title:e.label,onPress:e.onPress},e.label)):e,ListItem=forwardRef((e,t)=>{const{title:i,loading:s=!1,subtitle:o,description:n,titleLines:r=1,subtitleLines:l=1,left:a,icon:c,iconTone:d="primary",right:m,rightPlacement:h="auto",selectable:u=!1,checked:g=!1,onCheckedChange:p,actions:x,onPress:b,haptic:f,selected:y=!1,disabled:S=!1,size:j="md",divider:_=!1,chevron:w=!1,leftActions:I,rightActions:L,contextMenu:k,accessibilityLabel:v,accessibilityHint:z,style:V,containerStyle:F,titleStyle:A,subtitleStyle:C,descriptionStyle:B,leftSlotStyle:R,rightSlotStyle:H,testID:D}=e,P=useTheme(),T=useMemo(()=>sizeFor(P,j),[P,j]),E=useMemo(()=>buildStyles(P),[P]),{fontScale:M}=useWindowDimensions(),W=!!m&&("below"===h||"auto"===h&&M>1.2),O=useContextMenu(S?void 0:k,{haptic:f||!1,testID:D}),G=useMemo(()=>mergeRefs(t,O.hostRef),[t,O.hostRef]),Z=u||!!b,N=Z||O.enabled,K=N&&!S,{style:U,pressIn:X,pressOut:q}=usePressAnimation({enabled:K}),J=useFlickGuard(),Q=v??("string"==typeof i?i:void 0),isText=e=>"string"==typeof e||"number"==typeof e,Y=a??(void 0===c?null:_jsx(IconBadge,{icon:c,tone:d,size:BADGE_SIZE[j]})),$=u?_jsxs(View,{style:E.selectionLead,children:[_jsx(SelectionBox,{checked:g,disabled:S}),Y?_jsx(View,{style:E.selectionLeadContent,children:Y}):null]}):Y,ee=null!=x&&!1!==x&&!(Array.isArray(x)&&0===x.length),te=_&&!ee,ie=_jsxs(View,{style:[E.row,{paddingVertical:T.paddingVertical,minHeight:T.minHeight,backgroundColor:y?P.colors.surface.selected:"transparent"},te?E.divider:null,S?E.disabled:null,F],children:[$?_jsx(View,{style:[E.leftSlot,R],children:$}):null,_jsxs(View,{style:E.middle,children:[null==i||isText(i)?_jsx(Text,{style:[E.title,{fontSize:T.titleSize,...fontFor(P,"medium"),color:S?P.colors.text.disabled:P.colors.text.primary},A],numberOfLines:r,children:i??" "}):i,null==o||""===o?null:isText(o)?_jsx(Text,{style:[E.subtitle,{fontSize:T.subtitleSize,color:S?P.colors.text.disabled:P.colors.text.secondary},C],numberOfLines:l,children:o}):o,n?_jsx(Text,{style:[E.description,{fontSize:T.subtitleSize,color:S?P.colors.text.disabled:P.colors.text.tertiary},B],numberOfLines:2,children:n}):null,W?_jsx(View,{style:[E.rightBelow,H],children:m}):null]}),m&&!W||w?_jsxs(View,{style:[E.rightSlot,W?null:H],children:[W?null:m,w?_jsx(View,{style:m&&!W?E.chevronWithRight:null,children:_jsx(Chevron,{color:S?P.colors.text.disabled:P.colors.text.tertiary})}):null]}):null]}),se=N?_jsx(Animated.View,{style:[U,V],children:_jsx(Pressable,{ref:G,onPress:e=>{K&&Z&&!J.isFlick(e)&&(f&&triggerHaptic(f),u?p?.(!g):b?.(e))},onPressIn:e=>{J.onPressIn(e),X()},onPressOut:q,disabled:!K,accessibilityRole:u?"checkbox":b?"button":void 0,accessibilityLabel:Q,accessibilityHint:z,accessibilityState:u?{checked:g,disabled:!K}:{selected:y,disabled:!K},"aria-disabled":!K,...u?{"aria-checked":g}:{"aria-selected":y},testID:D,android_ripple:{color:P.colors.surface.pressed,borderless:!1},style:({pressed:e})=>e?E.pressed:null,...O.hostProps,children:ie})}):_jsx(View,{ref:t,accessibilityRole:"none",accessibilityLabel:Q,accessibilityHint:z,accessibilityState:{selected:y,disabled:S},"aria-selected":y,"aria-disabled":S,testID:D,style:V,children:ie}),oe=I&&I.length>0||L&&L.length>0,ne=ee?_jsxs(View,{style:[y?{backgroundColor:P.colors.surface.selected}:null,_?E.divider:null],children:[se,_jsx(View,{style:E.actions,children:renderActions(x)})]}):se,re=oe?_jsx(Swipeable,{leftActions:I,rightActions:L,accessibilityLabel:Q,children:ne}):ne;return s?_jsx(ListItemSkeleton,{...e}):O.enabled?_jsxs(_Fragment,{children:[re,O.renderSurface(_jsx(View,{style:E.preview,children:ie}))]}):re});ListItem.displayName="ListItem";const ListItemSkeleton=({subtitle:e,description:t,left:i,icon:s,right:o,chevron:n,size:r="md",containerStyle:l,style:a})=>{const c=useTheme(),d=sizeFor(c,r),m=Math.round(1.15*d.titleSize),h=Math.round(1.15*d.subtitleSize);return _jsxs(View,{style:[{flexDirection:"row",alignItems:"center",paddingHorizontal:c.spacing.md,paddingVertical:d.paddingVertical,minHeight:d.minHeight},l,a],children:[void 0!==i||void 0!==s?_jsx(View,{style:{marginRight:c.spacing.sm},children:_jsx(Skeleton,{shape:"circle",width:40,height:40})}):null,_jsxs(View,{style:{flex:1},children:[_jsx(Skeleton,{shape:"text",width:"70%",height:m,style:{marginBottom:c.spacing.xs}}),void 0!==e?_jsx(Skeleton,{shape:"text",width:"50%",height:h,style:void 0!==t?{marginBottom:c.spacing.xs}:void 0}):null,void 0!==t?_jsx(Skeleton,{shape:"text",width:"85%",height:h}):null]}),void 0!==o||n?_jsx(View,{style:{marginLeft:c.spacing.sm},children:_jsx(Skeleton,{width:20,height:20,radius:"sm"})}):null]})};ListItemSkeleton.displayName="ListItemSkeleton",ListItem.Skeleton=ListItemSkeleton;const buildStyles=e=>StyleSheet.create({row:{flexDirection:"row",alignItems:"center",paddingHorizontal:e.spacing.md},divider:{borderBottomWidth:StyleSheet.hairlineWidth,borderBottomColor:e.colors.border.primary},pressed:{backgroundColor:e.colors.surface.pressed},disabled:{opacity:.55},leftSlot:{marginRight:e.spacing.md,alignItems:"center",justifyContent:"center"},middle:{flex:1,flexDirection:"column",justifyContent:"center"},selectionLead:{flexDirection:"row",alignItems:"center"},selectionLeadContent:{marginLeft:e.spacing.sm},rightBelow:{alignSelf:"flex-start",flexDirection:"row",alignItems:"center",marginTop:e.spacing.xs},rightSlot:{marginLeft:e.spacing.md,alignItems:"center",justifyContent:"center",flexDirection:"row"},actions:{flexDirection:"row",flexWrap:"wrap",gap:e.spacing.sm,paddingHorizontal:e.spacing.md,paddingBottom:e.spacing.md},chevronWithRight:{marginLeft:e.spacing.xs},preview:{flex:1,backgroundColor:e.colors.background.elevated,borderRadius:e.radius.md,...smoothCorners,overflow:"hidden"},title:{letterSpacing:e.typography.letterSpacing.normal},subtitle:{marginTop:2,...fontFor(e,"normal")},description:{marginTop:2,...fontFor(e,"normal")}});export{ListItem};export default ListItem;
@@ -1 +1 @@
1
- "use strict";import{useEffect,useMemo,useRef,useState,useSyncExternalStore}from"react";import{AccessibilityInfo,Animated,BackHandler,Easing,StyleSheet}from"react-native";import{useReducedMotion}from"../../hooks/useReducedMotion.js";import{createAnimatedValue,useTheme}from"../../theme/index.js";import{Spinner}from"../Spinner/index.js";import{jsx as _jsx}from"react/jsx-runtime";const DEFAULT_SHOW_DELAY_MS=150,DEFAULT_MIN_VISIBLE_MS=400;let state={refCount:0,message:void 0};const listeners=new Set,notify=()=>{for(const e of listeners)e()},subscribe=e=>(listeners.add(e),()=>{listeners.delete(e)}),getState=()=>state,show=e=>{state={refCount:state.refCount+1,message:e??state.message},notify()},hide=()=>{if(state.refCount<=0)return;const e=state.refCount-1;state={refCount:e,message:0===e?void 0:state.message},notify()},reset=()=>{0===state.refCount&&void 0===state.message||(state={refCount:0,message:void 0},notify())},isVisible=()=>state.refCount>0,wrap=async(e,t)=>{show(t);try{return await("function"==typeof e?e():e)}finally{hide()}};export const loader={show:show,hide:hide,wrap:wrap,isVisible:isVisible,reset:reset};export const useLoader=()=>loader;export const LoaderOverlay=({renderIndicator:e,backdropColor:t,showDelayMs:s=150,minVisibleMs:r=400,testID:n})=>{const i=useTheme(),o=useReducedMotion(),a=useSyncExternalStore(subscribe,getState),[u,l]=useState(!1),c=useRef(null),f=useRef(null),d=useRef(null),m=useRef(createAnimatedValue(0)).current,y=a.refCount>0;useEffect(()=>{if(y)return null!==f.current&&(clearTimeout(f.current),f.current=null),void(u||null!==c.current||(c.current=setTimeout(()=>{c.current=null,0!==getState().refCount&&(d.current=Date.now(),l(!0))},s)));if(null!==c.current&&(clearTimeout(c.current),c.current=null),u&&null===f.current){const e=null!==d.current?Date.now()-d.current:r,t=Math.max(0,r-e);f.current=setTimeout(()=>{f.current=null,d.current=null,l(!1)},t)}},[y,u,s,r]),useEffect(()=>()=>{null!==c.current&&clearTimeout(c.current),null!==f.current&&clearTimeout(f.current)},[]),useEffect(()=>{u?o?m.setValue(1):Animated.timing(m,{toValue:1,duration:i.motion.duration.normal,easing:Easing.bezier(...i.motion.easing.standard),useNativeDriver:!0}).start():m.setValue(0)},[u,o,m,i]),useEffect(()=>{if(!u)return;const e=BackHandler.addEventListener("hardwareBackPress",()=>!0);return()=>{e.remove()}},[u]);const b=a.message;useEffect(()=>{u&&b&&AccessibilityInfo.announceForAccessibility(b)},[u,b]);const S=useMemo(()=>buildStyles(),[]);return u?_jsx(Animated.View,{pointerEvents:"auto",testID:n,accessible:!0,accessibilityViewIsModal:!0,accessibilityLiveRegion:"polite",accessibilityLabel:b??"Loading",accessibilityRole:"progressbar",accessibilityState:{busy:!0},"aria-busy":!0,style:[S.overlay,{backgroundColor:t??i.colors.background.overlay,opacity:m}],children:e?e(b):_jsx(Spinner,{size:"lg",message:b})}):null};const buildStyles=()=>StyleSheet.create({overlay:{...StyleSheet.absoluteFill,alignItems:"center",justifyContent:"center",zIndex:1e3}});
1
+ "use strict";import{useEffect,useMemo,useRef,useState,useSyncExternalStore}from"react";import{AccessibilityInfo,Animated,BackHandler,Easing,StyleSheet}from"react-native";import{usePresenceMotion}from"../../hooks/usePresenceMotion.js";import{createAnimatedValue,useTheme}from"../../theme/index.js";import{Spinner}from"../Spinner/index.js";import{jsx as _jsx}from"react/jsx-runtime";const DEFAULT_SHOW_DELAY_MS=150,DEFAULT_MIN_VISIBLE_MS=400;let state={refCount:0,message:void 0};const listeners=new Set,notify=()=>{for(const e of listeners)e()},subscribe=e=>(listeners.add(e),()=>{listeners.delete(e)}),getState=()=>state,show=e=>{state={refCount:state.refCount+1,message:e??state.message},notify()},hide=()=>{if(state.refCount<=0)return;const e=state.refCount-1;state={refCount:e,message:0===e?void 0:state.message},notify()},reset=()=>{0===state.refCount&&void 0===state.message||(state={refCount:0,message:void 0},notify())},isVisible=()=>state.refCount>0,wrap=async(e,t)=>{show(t);try{return await("function"==typeof e?e():e)}finally{hide()}};export const loader={show:show,hide:hide,wrap:wrap,isVisible:isVisible,reset:reset};export const useLoader=()=>loader;export const LoaderOverlay=({renderIndicator:e,backdropColor:t,showDelayMs:s=150,minVisibleMs:r=400,testID:n})=>{const i=useTheme(),o=usePresenceMotion().duration("normal"),a=useSyncExternalStore(subscribe,getState),[u,l]=useState(!1),c=useRef(null),f=useRef(null),m=useRef(null),d=useRef(createAnimatedValue(0)).current,y=a.refCount>0;useEffect(()=>{if(y)return null!==f.current&&(clearTimeout(f.current),f.current=null),void(u||null!==c.current||(c.current=setTimeout(()=>{c.current=null,0!==getState().refCount&&(m.current=Date.now(),l(!0))},s)));if(null!==c.current&&(clearTimeout(c.current),c.current=null),u&&null===f.current){const e=null!==m.current?Date.now()-m.current:r,t=Math.max(0,r-e);f.current=setTimeout(()=>{f.current=null,m.current=null,l(!1)},t)}},[y,u,s,r]),useEffect(()=>()=>{null!==c.current&&clearTimeout(c.current),null!==f.current&&clearTimeout(f.current)},[]),useEffect(()=>{u?Animated.timing(d,{toValue:1,duration:o,easing:Easing.bezier(...i.motion.easing.standard),useNativeDriver:!0}).start():d.setValue(0)},[u,o,d,i]),useEffect(()=>{if(!u)return;const e=BackHandler.addEventListener("hardwareBackPress",()=>!0);return()=>{e.remove()}},[u]);const b=a.message;useEffect(()=>{u&&b&&AccessibilityInfo.announceForAccessibility(b)},[u,b]);const S=useMemo(()=>buildStyles(),[]);return u?_jsx(Animated.View,{pointerEvents:"auto",testID:n,accessible:!0,accessibilityViewIsModal:!0,accessibilityLiveRegion:"polite",accessibilityLabel:b??"Loading",accessibilityRole:"progressbar",accessibilityState:{busy:!0},"aria-busy":!0,style:[S.overlay,{backgroundColor:t??i.colors.background.overlay,opacity:d}],children:e?e(b):_jsx(Spinner,{size:"lg",message:b})}):null};const buildStyles=()=>StyleSheet.create({overlay:{...StyleSheet.absoluteFill,alignItems:"center",justifyContent:"center",zIndex:1e3}});
@@ -1 +1 @@
1
- "use strict";import{useCallback,useEffect,useMemo,useRef,useState}from"react";import{Animated,Easing,Modal,Platform,Pressable,ScrollView,StyleSheet,useWindowDimensions,View}from"react-native";import{useSafeAreaInsets}from"react-native-safe-area-context";import{useReducedMotion}from"../../hooks/useReducedMotion.js";import{createAnimatedValue,setNativeValue,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{claimAnchoredSurface,computePlacement,PLACEMENT_MARGIN,placementRoom}from"../../utils/placement.js";import{Breakpoints}from"../../utils/responsive.js";import{AppIcon}from"../AppIcon/AppIcon.js";import{renderSlotIcon}from"../AppIcon/slotIcon.js";import{Divider}from"../Divider/index.js";import{ModalSafeArea,useModalInsets}from"../ModalSafeArea/ModalSafeArea.js";import{OptionSheet}from"../OptionSheet/index.js";import{Text}from"../Text/index.js";import{ToastHost}from"../Toast/ToastProvider.js";import{FOCUS_DELAY_MS,focusHost}from"./focusHost.js";import{visibleGroups,visibleTopActions,wantsSheet}from"./menuModel.js";import{webOnly}from"./webOnly.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const MENU_MIN_WIDTH=180,MENU_MAX_WIDTH=280,ROW_MIN_HEIGHT=48,TOP_ACTION_MIN_HEIGHT=64,ICON_SIZE=20,PREVIEW_LIFT=1.02,BACK_KEY="__menu-back",TOP_PREFIX="__menu-top:",WEB_CHECKABLE_ROLE=webOnly({role:"menuitemcheckbox"});export const MenuSurface=e=>{const{open:t,anchor:s,items:o,title:i,topActions:r,placement:n,presentation:l,unavailable:a,context:c=!1,preview:u,onClose:d,restoreFocusTo:m,haptic:p,accessibilityLabel:b,closeLabel:f,backLabel:h,testID:y}=e,x=useTheme(),g=useMemo(()=>buildStyles(x),[x]),_=useSafeAreaInsets(),[v,w]=useModalInsets(),j=useMemo(()=>({..._,top:v.top,bottom:v.bottom}),[_,v]),A=useWindowDimensions(),S=useReducedMotion(),I=useMemo(()=>visibleGroups(o,a),[o,a]),k=useMemo(()=>visibleTopActions(r,a),[r,a]),E="sheet"===l||"auto"===l&&A.width<Breakpoints.lg&&wantsSheet(I,k),[R,T]=useState(null),[M,C]=useState(null),L=useRef(d);L.current=d;const D=useRef(m);D.current=m;const O=useRef(null),P=useRef(!1),H=useRef(!1),V=useRef(new Map),B=useRef(null),N=useCallback(()=>{if(!P.current)return;P.current=!1;const e=O.current;O.current=null,e?e():focusHost(D.current?.())},[]);useEffect(()=>{if(t)return H.current=!0,P.current=!1,O.current=null,claimAnchoredSurface(()=>L.current());H.current&&(H.current=!1,P.current=!0,T(null),C(null),E||"ios"===Platform.OS||N())},[t]);const F=useCallback(e=>{if(e.disabled)return;const t=resolveHaptic(p,"selection");t&&triggerHaptic(t),e.key!==BACK_KEY?e.submenu?T(e):(O.current=e.onPress??null,L.current()):T(null)},[p]),K=useMemo(()=>({width:A.width,height:A.height,insets:j}),[A.width,A.height,j]),W=useMemo(()=>{if(!s||!M)return null;const e=s.x+s.width/2>K.width/2?"end":"start";return computePlacement(s,M,K,n,{align:e})},[s,M,K,n]);let G=K.height-j.top-j.bottom-2*PLACEMENT_MARGIN;if(s&&W){const e=placementRoom(s,K);G="top"===W.placement?e.above:e.below}const z=Math.min(280,K.width-j.left-j.right-2*PLACEMENT_MARGIN),$=t&&null!==W,Y=useRef(createAnimatedValue(0)).current,U=useRef(createAnimatedValue(1)).current;useEffect(()=>{if(!$)return setNativeValue(Y,0),void setNativeValue(U,1);const e=[Animated.timing(Y,{toValue:1,duration:x.motion.duration.fast,easing:Easing.bezier(...x.motion.easing.decelerate),useNativeDriver:!0})];c&&!S&&e.push(Animated.spring(U,{toValue:1.02,damping:x.motion.spring.snappy.damping,stiffness:x.motion.spring.snappy.stiffness,mass:x.motion.spring.snappy.mass,useNativeDriver:!0}));const t=Animated.parallel(e);return t.start(),()=>t.stop()},[$,c,S,Y,U,x.motion]);const X=useCallback(e=>{const{width:t,height:s}=e.nativeEvent.layout;C(e=>e&&e.width===t&&e.height===s?e:{width:t,height:s})},[]),q=c&&"top"===W?.placement,Z=R?.submenu?[R.submenu]:I,J=q?[...Z].reverse().map(e=>[...e].reverse()):Z,Q=[];if(R)Q.push({key:BACK_KEY,label:R.label});else for(const e of k)Q.push({key:`${TOP_PREFIX}${e.key}`,label:e.label,item:e});for(const e of J)for(const t of e)Q.push({key:t.key,label:t.label,item:t});const ee=Q[0]?.key;useEffect(()=>{if(!$||E||!ee)return;const e=setTimeout(()=>focusHost(V.current.get(ee)),FOCUS_DELAY_MS);return()=>clearTimeout(e)},[$,E,ee]);const setItemRef=e=>t=>{t?V.current.set(e,t):V.current.delete(e)},te=webOnly({onKeyDown:e=>{const t=e.key??e.nativeEvent?.key??"",s=Q.length,o=Q.findIndex(e=>e.key===B.current);let i=-1;if("ArrowDown"===t)i=(o+1)%s;else if("ArrowUp"===t)i=o<=0?s-1:o-1;else if("Home"===t)i=0;else if("End"===t)i=s-1;else{if("ArrowLeft"===t&&R)return e.preventDefault?.(),void T(null);if("ArrowRight"===t&&Q[o]?.item?.submenu)return e.preventDefault?.(),void F(Q[o].item);if(1===t.length&&""!==t.trim()){const e=t.toLowerCase();for(let t=1;t<=s;t+=1){const r=(o+t)%s;if(Q[r].label.toLowerCase().startsWith(e)){i=r;break}}}}i>=0&&(e.preventDefault?.(),(e=>{const t=Q[e];t&&focusHost(V.current.get(t.key))})(i))}});if(E){const e=R?.submenu?[{key:BACK_KEY,label:h,icon:"chevron-left"},...R.submenu]:[...k,...I.flat()],s=new Set(e.filter(e=>e.checked).map(e=>e.key));return _jsx(OptionSheet,{open:t,onClose:d,onAfterClose:N,title:R?.label??i,options:e,labelOf:e=>e.label,getValue:e=>e.key,disabledOf:e=>Boolean(e.disabled),destructiveOf:e=>Boolean(e.destructive),descriptionOf:e=>e.description,iconOf:e=>{const t=e;return renderSlotIcon(t.icon,{color:t.destructive?x.colors.toneText.error:x.colors.text.secondary,size:20,disabled:Boolean(t.disabled)})},isSelected:e=>s.has(String(e)),onSelect:e=>F(e),accessibilityLabel:b??i,testID:y?`${y}-sheet`:void 0})}const inkFor=e=>e.disabled?x.colors.text.disabled:e.destructive?x.colors.toneText.error:x.colors.text.primary,se=_jsxs(_Fragment,R?{children:[_jsxs(Pressable,{ref:setItemRef(BACK_KEY),onPress:()=>T(null),onFocus:()=>{B.current=BACK_KEY},accessibilityRole:"menuitem",accessibilityLabel:`${h}, ${R.label}`,android_ripple:{color:x.colors.surface.pressed,borderless:!1},style:({pressed:e})=>[g.row,e?g.pressed:null],children:[_jsx(View,{style:g.icon,children:_jsx(AppIcon,{name:"chevron-left",size:20,color:x.colors.text.secondary})}),_jsx(Text,{variant:"body",weight:"semibold",numberOfLines:1,style:g.labels,children:R.label})]}),_jsx(Divider,{spacing:"none"})]}:{children:[i?_jsx(Text,{variant:"caption",color:"secondary",accessibilityRole:"header",numberOfLines:2,style:g.title,children:i}):null,k.length>0?_jsxs(_Fragment,{children:[_jsx(View,{style:g.topRow,children:k.map(e=>{const t=`${TOP_PREFIX}${e.key}`,s=Boolean(e.disabled),o=inkFor(e);return _jsxs(Pressable,{ref:setItemRef(t),onPress:()=>F(e),onFocus:()=>{B.current=t},disabled:s,accessibilityRole:"menuitem",accessibilityLabel:e.accessibilityLabel??e.label,accessibilityState:{disabled:s},"aria-disabled":s,testID:e.testID,style:({pressed:e})=>[g.topAction,e?g.pressed:null],children:[renderSlotIcon(e.icon,{color:o,size:20,disabled:s}),_jsx(Text,{variant:"caption",color:o,numberOfLines:1,children:e.label})]},t)})}),_jsx(Divider,{spacing:"none"})]}):null]});return _jsx(Modal,{visible:t,transparent:!0,statusBarTranslucent:!0,presentationStyle:"overFullScreen",animationType:"none",onRequestClose:d,onDismiss:N,children:_jsxs(ModalSafeArea,{onInsets:w,children:[_jsx(Pressable,{style:[StyleSheet.absoluteFill,c?g.scrim:null],onPress:d,accessibilityRole:"button",accessibilityLabel:f,testID:y?`${y}-scrim`:void 0}),c&&u&&s?_jsx(Animated.View,{pointerEvents:"none",accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",style:[g.preview,{left:s.x,top:s.y,width:s.width,height:s.height,transform:[{scale:U}]}],children:u}):null,_jsx(Animated.View,{accessibilityRole:"menu",accessibilityLabel:R?.label??b??i,onLayout:X,testID:y?`${y}-menu`:void 0,...te,style:[g.anchored,{left:W?.x??0,top:W?.y??0,maxWidth:z,opacity:$?Y:0}],children:_jsx(View,{style:g.surface,children:_jsxs(View,{style:[g.clip,{maxHeight:G}],children:[se,_jsx(ScrollView,{style:g.scroll,bounces:!1,keyboardShouldPersistTaps:"handled",children:J.map((e,t)=>{const s=e.some(e=>null!=e.icon);return _jsxs(View,{children:[t>0?_jsx(Divider,{spacing:"none"}):null,e.map(e=>((e,t)=>{const s=Boolean(e.disabled),o=inkFor(e);return _jsxs(Pressable,{ref:setItemRef(e.key),onPress:()=>F(e),onFocus:()=>{B.current=e.key},disabled:s,accessibilityRole:"menuitem",accessibilityLabel:e.accessibilityLabel??e.label,accessibilityState:{disabled:s,checked:e.checked},"aria-disabled":s,"aria-checked":e.checked,...void 0!==e.checked?WEB_CHECKABLE_ROLE:null,android_ripple:{color:x.colors.surface.pressed,borderless:!1},testID:e.testID,style:({pressed:e})=>[g.row,e?g.pressed:null],children:[t?_jsx(View,{style:g.icon,children:renderSlotIcon(e.icon,{color:o,size:20,disabled:s})}):null,_jsxs(View,{style:g.labels,children:[_jsx(Text,{variant:"body",color:o,numberOfLines:2,children:e.label}),e.description?_jsx(Text,{variant:"caption",color:"secondary",numberOfLines:2,children:e.description}):null]}),e.detail?_jsx(Text,{variant:"caption",color:"tertiary",children:e.detail}):null,e.checked?_jsx(AppIcon,{name:"check",size:20,color:x.colors.primary}):null,e.submenu?_jsx(AppIcon,{name:"chevron-right",size:20,color:x.colors.text.tertiary}):null]},e.key)})(e,s))]},e[0].key)})})]})})}),_jsx(ToastHost,{})]})})};const buildStyles=e=>StyleSheet.create({scrim:{backgroundColor:e.colors.background.overlay},preview:{position:"absolute"},anchored:{position:"absolute",minWidth:180},surface:{backgroundColor:e.colors.background.elevated,borderRadius:e.radius.md,...smoothCorners,...e.shadows.lg},clip:{borderRadius:e.radius.md,...smoothCorners,overflow:"hidden"},scroll:{flexGrow:0,flexShrink:1},title:{paddingHorizontal:e.spacing.md,paddingTop:e.spacing.sm,paddingBottom:e.spacing.xs},row:{flexDirection:"row",alignItems:"center",gap:e.spacing.md,minHeight:48,paddingHorizontal:e.spacing.md,paddingVertical:e.spacing.sm},pressed:{backgroundColor:e.colors.surface.pressed},icon:{width:20,alignItems:"center"},labels:{flexGrow:1,flexShrink:1},topRow:{flexDirection:"row",padding:e.spacing.xs,gap:e.spacing.xs},topAction:{flexGrow:1,flexBasis:0,alignItems:"center",justifyContent:"center",gap:e.spacing.xs,minHeight:64,borderRadius:e.radius.sm,...smoothCorners}});
1
+ "use strict";import{useCallback,useEffect,useMemo,useRef,useState}from"react";import{Animated,Easing,Modal,Platform,Pressable,ScrollView,StyleSheet,useWindowDimensions,View}from"react-native";import{useSafeAreaInsets}from"react-native-safe-area-context";import{usePresenceMotion}from"../../hooks/usePresenceMotion.js";import{createAnimatedValue,setNativeValue,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{claimAnchoredSurface,computePlacement,PLACEMENT_MARGIN,placementRoom}from"../../utils/placement.js";import{Breakpoints}from"../../utils/responsive.js";import{AppIcon}from"../AppIcon/AppIcon.js";import{renderSlotIcon}from"../AppIcon/slotIcon.js";import{Divider}from"../Divider/index.js";import{ModalSafeArea,useModalInsets}from"../ModalSafeArea/ModalSafeArea.js";import{OptionSheet}from"../OptionSheet/index.js";import{Text}from"../Text/index.js";import{ToastHost}from"../Toast/ToastProvider.js";import{FOCUS_DELAY_MS,focusHost}from"./focusHost.js";import{visibleGroups,visibleTopActions,wantsSheet}from"./menuModel.js";import{webOnly}from"./webOnly.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const MENU_MIN_WIDTH=180,MENU_MAX_WIDTH=280,ROW_MIN_HEIGHT=48,TOP_ACTION_MIN_HEIGHT=64,ICON_SIZE=20,PREVIEW_LIFT=1.02,BACK_KEY="__menu-back",TOP_PREFIX="__menu-top:",WEB_CHECKABLE_ROLE=webOnly({role:"menuitemcheckbox"});export const MenuSurface=e=>{const{open:s,anchor:t,items:o,title:i,topActions:r,placement:n,presentation:l,unavailable:a,context:c=!1,preview:u,onClose:d,restoreFocusTo:m,haptic:p,accessibilityLabel:b,closeLabel:f,backLabel:h,testID:y}=e,x=useTheme(),g=useMemo(()=>buildStyles(x),[x]),_=useSafeAreaInsets(),[v,w]=useModalInsets(),j=useMemo(()=>({..._,top:v.top,bottom:v.bottom}),[_,v]),A=useWindowDimensions(),S=usePresenceMotion(),I=S.duration("fast"),k=useMemo(()=>visibleGroups(o,a),[o,a]),E=useMemo(()=>visibleTopActions(r,a),[r,a]),T="sheet"===l||"auto"===l&&A.width<Breakpoints.lg&&wantsSheet(k,E),[M,C]=useState(null),[R,L]=useState(null),P=useRef(d);P.current=d;const D=useRef(m);D.current=m;const O=useRef(null),H=useRef(!1),V=useRef(!1),B=useRef(new Map),N=useRef(null),F=useCallback(()=>{if(!H.current)return;H.current=!1;const e=O.current;O.current=null,e?e():focusHost(D.current?.())},[]);useEffect(()=>{if(s)return V.current=!0,H.current=!1,O.current=null,claimAnchoredSurface(()=>P.current());V.current&&(V.current=!1,H.current=!0,C(null),L(null),T||"ios"===Platform.OS||F())},[s]);const K=useCallback(e=>{if(e.disabled)return;const s=resolveHaptic(p,"selection");s&&triggerHaptic(s),e.key!==BACK_KEY?e.submenu?C(e):(O.current=e.onPress??null,P.current()):C(null)},[p]),W=useMemo(()=>({width:A.width,height:A.height,insets:j}),[A.width,A.height,j]),G=useMemo(()=>{if(!t||!R)return null;const e=t.x+t.width/2>W.width/2?"end":"start";return computePlacement(t,R,W,n,{align:e})},[t,R,W,n]);let z=W.height-j.top-j.bottom-2*PLACEMENT_MARGIN;if(t&&G){const e=placementRoom(t,W);z="top"===G.placement?e.above:e.below}const $=Math.min(280,W.width-j.left-j.right-2*PLACEMENT_MARGIN),Y=s&&null!==G,U=useRef(createAnimatedValue(0)).current,X=useRef(createAnimatedValue(1)).current;useEffect(()=>{if(!Y)return setNativeValue(U,0),void setNativeValue(X,1);const e=[Animated.timing(U,{toValue:1,duration:I,easing:Easing.bezier(...x.motion.easing.decelerate),useNativeDriver:!0})];c&&!S.reduced&&e.push(Animated.spring(X,{toValue:1.02,damping:x.motion.spring.snappy.damping,stiffness:x.motion.spring.snappy.stiffness,mass:x.motion.spring.snappy.mass,useNativeDriver:!0}));const s=Animated.parallel(e);return s.start(),()=>s.stop()},[Y,c,S.reduced,U,X,x.motion,I]);const q=useCallback(e=>{const{width:s,height:t}=e.nativeEvent.layout;L(e=>e&&e.width===s&&e.height===t?e:{width:s,height:t})},[]),Z=c&&"top"===G?.placement,J=M?.submenu?[M.submenu]:k,Q=Z?[...J].reverse().map(e=>[...e].reverse()):J,ee=[];if(M)ee.push({key:BACK_KEY,label:M.label});else for(const e of E)ee.push({key:`${TOP_PREFIX}${e.key}`,label:e.label,item:e});for(const e of Q)for(const s of e)ee.push({key:s.key,label:s.label,item:s});const se=ee[0]?.key;useEffect(()=>{if(!Y||T||!se)return;const e=setTimeout(()=>focusHost(B.current.get(se)),FOCUS_DELAY_MS);return()=>clearTimeout(e)},[Y,T,se]);const setItemRef=e=>s=>{s?B.current.set(e,s):B.current.delete(e)},te=webOnly({onKeyDown:e=>{const s=e.key??e.nativeEvent?.key??"",t=ee.length,o=ee.findIndex(e=>e.key===N.current);let i=-1;if("ArrowDown"===s)i=(o+1)%t;else if("ArrowUp"===s)i=o<=0?t-1:o-1;else if("Home"===s)i=0;else if("End"===s)i=t-1;else{if("ArrowLeft"===s&&M)return e.preventDefault?.(),void C(null);if("ArrowRight"===s&&ee[o]?.item?.submenu)return e.preventDefault?.(),void K(ee[o].item);if(1===s.length&&""!==s.trim()){const e=s.toLowerCase();for(let s=1;s<=t;s+=1){const r=(o+s)%t;if(ee[r].label.toLowerCase().startsWith(e)){i=r;break}}}}i>=0&&(e.preventDefault?.(),(e=>{const s=ee[e];s&&focusHost(B.current.get(s.key))})(i))}});if(T){const e=M?.submenu?[{key:BACK_KEY,label:h,icon:"chevron-left"},...M.submenu]:[...E,...k.flat()],t=new Set(e.filter(e=>e.checked).map(e=>e.key));return _jsx(OptionSheet,{open:s,onClose:d,onAfterClose:F,title:M?.label??i,options:e,labelOf:e=>e.label,getValue:e=>e.key,disabledOf:e=>Boolean(e.disabled),destructiveOf:e=>Boolean(e.destructive),descriptionOf:e=>e.description,iconOf:e=>{const s=e;return renderSlotIcon(s.icon,{color:s.destructive?x.colors.toneText.error:x.colors.text.secondary,size:20,disabled:Boolean(s.disabled)})},isSelected:e=>t.has(String(e)),onSelect:e=>K(e),accessibilityLabel:b??i,testID:y?`${y}-sheet`:void 0})}const inkFor=e=>e.disabled?x.colors.text.disabled:e.destructive?x.colors.toneText.error:x.colors.text.primary,oe=_jsxs(_Fragment,M?{children:[_jsxs(Pressable,{ref:setItemRef(BACK_KEY),onPress:()=>C(null),onFocus:()=>{N.current=BACK_KEY},accessibilityRole:"menuitem",accessibilityLabel:`${h}, ${M.label}`,android_ripple:{color:x.colors.surface.pressed,borderless:!1},style:({pressed:e})=>[g.row,e?g.pressed:null],children:[_jsx(View,{style:g.icon,children:_jsx(AppIcon,{name:"chevron-left",size:20,color:x.colors.text.secondary})}),_jsx(Text,{variant:"body",weight:"semibold",numberOfLines:1,style:g.labels,children:M.label})]}),_jsx(Divider,{spacing:"none"})]}:{children:[i?_jsx(Text,{variant:"caption",color:"secondary",accessibilityRole:"header",numberOfLines:2,style:g.title,children:i}):null,E.length>0?_jsxs(_Fragment,{children:[_jsx(View,{style:g.topRow,children:E.map(e=>{const s=`${TOP_PREFIX}${e.key}`,t=Boolean(e.disabled),o=inkFor(e);return _jsxs(Pressable,{ref:setItemRef(s),onPress:()=>K(e),onFocus:()=>{N.current=s},disabled:t,accessibilityRole:"menuitem",accessibilityLabel:e.accessibilityLabel??e.label,accessibilityState:{disabled:t},"aria-disabled":t,testID:e.testID,style:({pressed:e})=>[g.topAction,e?g.pressed:null],children:[renderSlotIcon(e.icon,{color:o,size:20,disabled:t}),_jsx(Text,{variant:"caption",color:o,numberOfLines:1,children:e.label})]},s)})}),_jsx(Divider,{spacing:"none"})]}):null]});return _jsx(Modal,{visible:s,transparent:!0,statusBarTranslucent:!0,presentationStyle:"overFullScreen",animationType:"none",onRequestClose:d,onDismiss:F,children:_jsxs(ModalSafeArea,{onInsets:w,children:[_jsx(Pressable,{style:[StyleSheet.absoluteFill,c?g.scrim:null],onPress:d,accessibilityRole:"button",accessibilityLabel:f,testID:y?`${y}-scrim`:void 0}),c&&u&&t?_jsx(Animated.View,{pointerEvents:"none",accessibilityElementsHidden:!0,importantForAccessibility:"no-hide-descendants",style:[g.preview,{left:t.x,top:t.y,width:t.width,height:t.height,transform:[{scale:X}]}],children:u}):null,_jsx(Animated.View,{accessibilityRole:"menu",accessibilityLabel:M?.label??b??i,onLayout:q,testID:y?`${y}-menu`:void 0,...te,style:[g.anchored,{left:G?.x??0,top:G?.y??0,maxWidth:$,opacity:Y?U:0}],children:_jsx(View,{style:g.surface,children:_jsxs(View,{style:[g.clip,{maxHeight:z}],children:[oe,_jsx(ScrollView,{style:g.scroll,bounces:!1,keyboardShouldPersistTaps:"handled",children:Q.map((e,s)=>{const t=e.some(e=>null!=e.icon);return _jsxs(View,{children:[s>0?_jsx(Divider,{spacing:"none"}):null,e.map(e=>((e,s)=>{const t=Boolean(e.disabled),o=inkFor(e);return _jsxs(Pressable,{ref:setItemRef(e.key),onPress:()=>K(e),onFocus:()=>{N.current=e.key},disabled:t,accessibilityRole:"menuitem",accessibilityLabel:e.accessibilityLabel??e.label,accessibilityState:{disabled:t,checked:e.checked},"aria-disabled":t,"aria-checked":e.checked,...void 0!==e.checked?WEB_CHECKABLE_ROLE:null,android_ripple:{color:x.colors.surface.pressed,borderless:!1},testID:e.testID,style:({pressed:e})=>[g.row,e?g.pressed:null],children:[s?_jsx(View,{style:g.icon,children:renderSlotIcon(e.icon,{color:o,size:20,disabled:t})}):null,_jsxs(View,{style:g.labels,children:[_jsx(Text,{variant:"body",color:o,numberOfLines:2,children:e.label}),e.description?_jsx(Text,{variant:"caption",color:"secondary",numberOfLines:2,children:e.description}):null]}),e.detail?_jsx(Text,{variant:"caption",color:"tertiary",children:e.detail}):null,e.checked?_jsx(AppIcon,{name:"check",size:20,color:x.colors.primary}):null,e.submenu?_jsx(AppIcon,{name:"chevron-right",size:20,color:x.colors.text.tertiary}):null]},e.key)})(e,t))]},e[0].key)})})]})})}),_jsx(ToastHost,{})]})})};const buildStyles=e=>StyleSheet.create({scrim:{backgroundColor:e.colors.background.overlay},preview:{position:"absolute"},anchored:{position:"absolute",minWidth:180},surface:{backgroundColor:e.colors.background.elevated,borderRadius:e.radius.md,...smoothCorners,...e.shadows.lg},clip:{borderRadius:e.radius.md,...smoothCorners,overflow:"hidden"},scroll:{flexGrow:0,flexShrink:1},title:{paddingHorizontal:e.spacing.md,paddingTop:e.spacing.sm,paddingBottom:e.spacing.xs},row:{flexDirection:"row",alignItems:"center",gap:e.spacing.md,minHeight:48,paddingHorizontal:e.spacing.md,paddingVertical:e.spacing.sm},pressed:{backgroundColor:e.colors.surface.pressed},icon:{width:20,alignItems:"center"},labels:{flexGrow:1,flexShrink:1},topRow:{flexDirection:"row",padding:e.spacing.xs,gap:e.spacing.xs},topAction:{flexGrow:1,flexBasis:0,alignItems:"center",justifyContent:"center",gap:e.spacing.xs,minHeight:64,borderRadius:e.radius.sm,...smoothCorners}});
@@ -1 +1 @@
1
- "use strict";import{formatTime}from"@webority/mobile-core";import{useCallback,useEffect,useMemo,useRef}from"react";import{Pressable,StyleSheet,View}from"react-native";import{useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{AppIcon}from"../AppIcon/index.js";import{Button}from"../Button/index.js";import{Markdown}from"../Markdown/index.js";import{Text}from"../Text/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const DEFAULT_MESSAGE_BUBBLE_LABELS=Object.freeze({you:"You",sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",retry:"Try again",replyTo:e=>e?`Reply to ${e}`:"Reply"});const RUN_GAP=2,MAX_WIDTH="85%",STATUS_ICON=14,statusIcon=e=>{switch(e){case"sending":return"clock";case"sent":return"check";case"failed":return"alert-circle";default:return"check-check"}},statusColour=(e,t)=>{switch(t){case"read":return e.colors.toneText.info;case"failed":return e.colors.toneText.error;default:return e.colors.text.tertiary}};export const MessageBubble=({side:e,text:t,children:s,markdown:r=!1,groupPosition:o="single",author:n,time:i,status:a,replyTo:l,streaming:c=!1,error:d,onRetry:u,actions:m,onLongPress:p,footer:b,labels:x,haptic:f,style:y,testID:g})=>{const h=useTheme(),T=useMemo(()=>buildStyles(h),[h]),j=x?{...DEFAULT_MESSAGE_BUBBLE_LABELS,...x}:DEFAULT_MESSAGE_BUBBLE_LABELS,_="mine"===e,L="single"===o||"first"===o,S="single"===o||"last"===o,B=null==i?"":formatTime(i),A=("failed"===a||Boolean(d))&&Boolean(u),E=_?j.you:n??"",v=useMemo(()=>{const e=m?[...m]:[];return l?.onPress&&e.push({name:"openReply",label:j.replyTo(l.author),onPress:l.onPress}),A&&u&&e.push({name:"retry",label:j.retry,onPress:u}),e},[m,l,A,u,j]),P=!s||(m?.length??0)>0,I=a&&_?j[a]:"",M=[E,B,t,l?`${j.replyTo(l.author)}: ${l.text}`:"",I].filter(Boolean).join(", "),R=useRef(c);useEffect(()=>{R.current&&!c&&!d&&t&&announce(E?`${E}, ${t}`:t),R.current=c},[c,d,t,E]);const k=useRef(d);useEffect(()=>{d&&d!==k.current&&announce(d,{polite:!1}),k.current=d},[d]);const w=useCallback(()=>{const e=resolveHaptic(f,"longPress");e&&triggerHaptic(e),p?.()},[f,p]),C=useCallback(e=>{v.find(t=>t.name===e.nativeEvent.actionName)?.onPress()},[v]),D=h.radius.xl,$=h.radius.xs,H=_?{borderTopRightRadius:L?D:$,borderBottomRightRadius:S?D:$}:{borderTopLeftRadius:L?D:$,borderBottomLeftRadius:S?D:$},U=s??(r?_jsx(Markdown,{children:t}):_jsx(Text,{variant:"body",children:t})),z=l?_jsxs(Pressable,{onPress:l.onPress,disabled:!l.onPress,accessibilityRole:l.onPress?"button":void 0,accessibilityLabel:`${j.replyTo(l.author)}: ${l.text}`,style:T.quote,children:[l.author?_jsx(Text,{variant:"caption",weight:"semibold",color:"link",numberOfLines:1,children:l.author}):null,_jsx(Text,{variant:"bodySmall",color:"secondary",numberOfLines:2,children:l.text})]}):null,V=[T.bubble,_?T.mine:T.theirs,H],F=P?{accessible:!0,accessibilityLabel:M,accessibilityState:{busy:c},"aria-busy":c,accessibilityActions:v.map(({name:e,label:t})=>({name:e,label:t})),onAccessibilityAction:C}:{accessible:!1},O=(m?.length??0)>0?_jsxs(Pressable,{onLongPress:w,delayLongPress:350,style:V,testID:g?`${g}-bubble`:void 0,...F,children:[z,U]}):_jsxs(View,{style:V,testID:g?`${g}-bubble`:void 0,...F,children:[z,U]}),G=S&&(""!==B||_&&a);return _jsxs(View,{style:[T.root,_?T.rootMine:T.rootTheirs,{marginTop:L?h.spacing.sm:2},y],testID:g,children:[!_&&L&&n?_jsx(Text,{variant:"caption",color:"secondary",style:T.author,numberOfLines:1,importantForAccessibility:P?"no-hide-descendants":"auto",accessibilityElementsHidden:P,children:n}):null,O,G?_jsxs(View,{style:[T.meta,_?T.metaMine:null],importantForAccessibility:P?"no-hide-descendants":"auto",accessibilityElementsHidden:P,children:[B?_jsx(Text,{variant:"caption",color:"tertiary",children:B}):null,_&&a?_jsx(AppIcon,{name:statusIcon(a),size:14,color:statusColour(h,a),accessibilityLabel:j[a],testID:g?`${g}-status-${a}`:void 0}):null]}):null,d?_jsx(Text,{variant:"bodySmall",color:"error",style:_?T.endText:null,children:d}):null,A?_jsx(Button,{title:j.retry,variant:"link",size:"sm",leftIcon:"refresh-cw",onPress:u,testID:g?`${g}-retry`:void 0}):null,b]})};const buildStyles=e=>StyleSheet.create({root:{maxWidth:"85%",gap:e.spacing.xs},rootMine:{alignSelf:"flex-end",alignItems:"flex-end"},rootTheirs:{alignSelf:"flex-start",alignItems:"flex-start"},author:{paddingHorizontal:e.spacing.md},bubble:{borderRadius:e.radius.xl,...smoothCorners,paddingHorizontal:e.spacing.md,paddingVertical:e.spacing.sm,gap:e.spacing.xs},mine:{backgroundColor:e.colors.primaryMuted},theirs:{backgroundColor:e.colors.background.secondary},quote:{borderLeftWidth:3,borderLeftColor:e.colors.primary,paddingLeft:e.spacing.sm,paddingVertical:e.spacing.xs},meta:{flexDirection:"row",alignItems:"center",gap:e.spacing.xs,paddingHorizontal:e.spacing.xs},metaMine:{justifyContent:"flex-end"},endText:{textAlign:"right"}});export default MessageBubble;
1
+ "use strict";import{formatTime}from"@webority/mobile-core";import{useCallback,useEffect,useMemo,useRef}from"react";import{Pressable,StyleSheet,View}from"react-native";import{useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{smoothCorners}from"../../utils/corners.js";import{AppIcon}from"../AppIcon/index.js";import{Button}from"../Button/index.js";import{Markdown}from"../Markdown/index.js";import{useContextMenu}from"../Menu/useContextMenu.js";import{Text}from"../Text/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const DEFAULT_MESSAGE_BUBBLE_LABELS=Object.freeze({you:"You",sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",retry:"Try again",copy:"Copy",replyTo:e=>e?`Reply to ${e}`:"Reply"});const RUN_GAP=2,MAX_WIDTH="85%",STATUS_ICON=14,statusIcon=e=>{switch(e){case"sending":return"clock";case"sent":return"check";case"failed":return"alert-circle";default:return"check-check"}},statusColour=(e,t)=>{switch(t){case"read":return e.colors.toneText.info;case"failed":return e.colors.toneText.error;default:return e.colors.text.tertiary}};export const MessageBubble=({side:e,text:t,children:s,markdown:o=!1,groupPosition:r="single",author:n,time:i,status:a,replyTo:l,streaming:c=!1,error:u,onRetry:d,actions:m,onCopy:p,onLongPress:b,footer:x,labels:y,haptic:f,style:h,testID:g})=>{const T=useTheme(),j=useMemo(()=>buildStyles(T),[T]),_=y?{...DEFAULT_MESSAGE_BUBBLE_LABELS,...y}:DEFAULT_MESSAGE_BUBBLE_LABELS,L="mine"===e,S="single"===r||"first"===r,P="single"===r||"last"===r,B=null==i?"":formatTime(i),M=("failed"===a||Boolean(u))&&Boolean(d),A=L?_.you:n??"",E=useMemo(()=>{const e=[];return p&&!m?.some(e=>"copy"===e.name)&&e.push({name:"copy",label:_.copy,onPress:()=>p(t)}),m&&e.push(...m),l?.onPress&&e.push({name:"openReply",label:_.replyTo(l.author),onPress:l.onPress}),M&&d&&e.push({name:"retry",label:_.retry,onPress:d}),e},[m,p,t,l,M,d,_]),v=(m?.length??0)>0||Boolean(p),I=useMemo(()=>v?{items:E.map(({name:e,label:t,onPress:s})=>({key:e,label:t,onPress:s}))}:void 0,[v,E]),R=useContextMenu(I,{haptic:f,testID:g}),k=R.hostProps.onLongPress,C=!s||(m?.length??0)>0,w=a&&L?_[a]:"",D=[A,B,t,l?`${_.replyTo(l.author)}: ${l.text}`:"",w].filter(Boolean).join(", "),$=useRef(c);useEffect(()=>{$.current&&!c&&!u&&t&&announce(A?`${A}, ${t}`:t),$.current=c},[c,u,t,A]);const U=useRef(u);useEffect(()=>{u&&u!==U.current&&announce(u,{polite:!1}),U.current=u},[u]);const z=useCallback(e=>{k?.(e),b?.()},[k,b]),H=useCallback(e=>{E.find(t=>t.name===e.nativeEvent.actionName)?.onPress()},[E]),V=T.radius.xl,F=T.radius.xs,O=L?{borderTopRightRadius:S?V:F,borderBottomRightRadius:P?V:F}:{borderTopLeftRadius:S?V:F,borderBottomLeftRadius:P?V:F},G=s??(o?_jsx(Markdown,{children:t}):_jsx(Text,{variant:"body",children:t})),N=l?_jsxs(Pressable,{onPress:l.onPress,disabled:!l.onPress,accessibilityRole:l.onPress?"button":void 0,accessibilityLabel:`${_.replyTo(l.author)}: ${l.text}`,style:j.quote,children:[l.author?_jsx(Text,{variant:"caption",weight:"semibold",color:"link",numberOfLines:1,children:l.author}):null,_jsx(Text,{variant:"bodySmall",color:"secondary",numberOfLines:2,children:l.text})]}):null,W=[j.bubble,L?j.mine:j.theirs,O],q=C?{accessible:!0,accessibilityLabel:D,accessibilityState:{busy:c},"aria-busy":c,accessibilityActions:E.map(({name:e,label:t})=>({name:e,label:t})),onAccessibilityAction:H}:{accessible:!1},X=v?_jsxs(Pressable,{ref:R.hostRef,...R.hostProps,onLongPress:z,delayLongPress:350,style:W,testID:g?`${g}-bubble`:void 0,...q,children:[N,G]}):_jsxs(View,{style:W,testID:g?`${g}-bubble`:void 0,...q,children:[N,G]}),Y=P&&(""!==B||L&&a);return _jsxs(View,{style:[j.root,L?j.rootMine:j.rootTheirs,{marginTop:S?T.spacing.sm:2},h],testID:g,children:[!L&&S&&n?_jsx(Text,{variant:"caption",color:"secondary",style:j.author,numberOfLines:1,importantForAccessibility:C?"no-hide-descendants":"auto",accessibilityElementsHidden:C,children:n}):null,X,R.renderSurface(),Y?_jsxs(View,{style:[j.meta,L?j.metaMine:null],importantForAccessibility:C?"no-hide-descendants":"auto",accessibilityElementsHidden:C,children:[B?_jsx(Text,{variant:"caption",color:"tertiary",children:B}):null,L&&a?_jsx(AppIcon,{name:statusIcon(a),size:14,color:statusColour(T,a),accessibilityLabel:_[a],testID:g?`${g}-status-${a}`:void 0}):null]}):null,u?_jsx(Text,{variant:"bodySmall",color:"error",style:L?j.endText:null,children:u}):null,M?_jsx(Button,{title:_.retry,variant:"link",size:"sm",leftIcon:"refresh-cw",onPress:d,testID:g?`${g}-retry`:void 0}):null,x]})};const buildStyles=e=>StyleSheet.create({root:{maxWidth:"85%",gap:e.spacing.xs},rootMine:{alignSelf:"flex-end",alignItems:"flex-end"},rootTheirs:{alignSelf:"flex-start",alignItems:"flex-start"},author:{paddingHorizontal:e.spacing.md},bubble:{borderRadius:e.radius.xl,...smoothCorners,paddingHorizontal:e.spacing.md,paddingVertical:e.spacing.sm,gap:e.spacing.xs},mine:{backgroundColor:e.colors.primaryMuted},theirs:{backgroundColor:e.colors.background.secondary},quote:{borderLeftWidth:3,borderLeftColor:e.colors.primary,paddingLeft:e.spacing.sm,paddingVertical:e.spacing.xs},meta:{flexDirection:"row",alignItems:"center",gap:e.spacing.xs,paddingHorizontal:e.spacing.xs},metaMine:{justifyContent:"flex-end"},endText:{textAlign:"right"}});export default MessageBubble;
@@ -1 +1 @@
1
- "use strict";import{forwardRef,useCallback,useEffect,useMemo,useRef,useState}from"react";import{AccessibilityInfo,Animated,Dimensions,Easing,Platform,Pressable,Modal as RNModal,StyleSheet,View}from"react-native";import{createAnimatedValue,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{squircleHostRadius}from"../../utils/squircle.js";import{ModalSafeArea,useModalInsets}from"../ModalSafeArea/ModalSafeArea.js";import{SquircleFill,useSquircle}from"../SquircleFill/SquircleFill.js";import{ToastHost}from"../Toast/ToastProvider.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const MODAL_DISMISS_GRACE_MS=300;const Modal=forwardRef((e,t)=>{const{visible:s,onRequestClose:o,presentation:r="centered",backdropOpacity:i,backdropPressClose:a=!0,animationDuration:n,accessibilityLabel:l,hardwareBackPress:c=!0,children:u,contentStyle:d,backdropStyle:m,restoreFocusRef:f,onDismissed:p,haptic:g,testID:b}=e,h=useTheme(),[S,y]=useModalInsets(),x=n??h.motion.duration.normal,v=Dimensions.get("window").height,A=h.components.modal,M=A?.scaleStartValue??.9,C=useRef(createAnimatedValue(M)).current,R=useRef(createAnimatedValue(0)).current,j=useRef(createAnimatedValue(v)).current,w=useRef(null),T=useRef(!1),[k,V]=useState(s),D=useMemo(()=>buildStyles(h),[h]),_=useMemo(()=>{const e=h.colors.background.overlay;if("number"!=typeof i)return e;const t=e.match(/^rgba?\(([^)]+)\)$/);if(!t)return e;const[s,o,r]=t[1].split(",").map(e=>e.trim());return`rgba(${s}, ${o}, ${r}, ${i})`},[h.colors.background.overlay,i]);useEffect(()=>{s&&V(!0)},[s]),useEffect(()=>{const e=[];if(s&&k)if("bottom"===r){const t=Animated.spring(j,{toValue:0,damping:h.motion.spring.gentle.damping,stiffness:h.motion.spring.gentle.stiffness,mass:h.motion.spring.gentle.mass,useNativeDriver:!0});t.start(),e.push(t)}else{const t=Animated.parallel([Animated.spring(C,{toValue:1,damping:h.motion.spring.gentle.damping,stiffness:h.motion.spring.gentle.stiffness,mass:h.motion.spring.gentle.mass,useNativeDriver:!0}),Animated.timing(R,{toValue:1,duration:x,useNativeDriver:!0})]);t.start(),e.push(t)}else if(k){const t=h.motion.duration.fast,s=Easing.bezier(...h.motion.easing.accelerate),o=Animated.parallel(["bottom"===r?Animated.timing(j,{toValue:v,duration:t,easing:s,useNativeDriver:!0}):Animated.parallel([Animated.timing(C,{toValue:M,duration:t,easing:s,useNativeDriver:!0}),Animated.timing(R,{toValue:0,duration:t,easing:s,useNativeDriver:!0})])]);o.start(({finished:e})=>{e&&V(!1)}),e.push(o)}return()=>e.forEach(e=>e.stop())},[s,k,r,x,C,R,j,v,h.motion.spring.gentle.damping,h.motion.spring.gentle.stiffness,h.motion.spring.gentle.mass,h.motion.duration.fast,h.motion.easing.accelerate,M]),useEffect(()=>{if("web"===Platform.OS)return;let e,t;return s?(e=setTimeout(()=>{w.current&&AccessibilityInfo.sendAccessibilityEvent(w.current,"focus")},150),T.current=!0):T.current&&(T.current=!1,f&&f.current&&(t=setTimeout(()=>{const e=f.current;e&&AccessibilityInfo.sendAccessibilityEvent(e,"focus")},x))),()=>{e&&clearTimeout(e),t&&clearTimeout(t)}},[s,x,f]);const E=useRef(!1);useEffect(()=>{if(s)return void(E.current=!0);if(!E.current)return;if(E.current=!1,!p)return;const e=setTimeout(p,300);return()=>clearTimeout(e)},[s,p]);const I=useCallback(()=>{if(!a)return;const e=resolveHaptic(g,"selection");e&&triggerHaptic(e),o()},[a,o,g]),q=useCallback(()=>{c&&o()},[c,o]),z=useSquircle("bottom"!==r&&"fullScreen"!==r,h.radius.xl),H=useMemo(()=>"fullScreen"===r?[D.fullScreenContent,{backgroundColor:h.colors.background.elevated}]:"bottom"===r?[D.bottomContent,{backgroundColor:h.colors.background.elevated,borderTopLeftRadius:h.radius.xl,borderTopRightRadius:h.radius.xl,...smoothCorners,paddingTop:h.spacing.lg,paddingHorizontal:h.spacing.lg,paddingBottom:h.spacing.lg+S.bottom},h.shadows.xl]:[D.centeredContent,{backgroundColor:h.colors.background.elevated,borderRadius:z.active&&z.size?squircleHostRadius(z.size.width,z.size.height,h.radius.xl):h.radius.xl,...smoothCorners,padding:h.spacing.xl},h.shadows.xl],[r,h,D,S.bottom,z.active,z.size]),N=useMemo(()=>"bottom"===r?D.bottomWrapper:"fullScreen"===r?D.fullScreenWrapper:D.centeredWrapper,[r,D]),P=useMemo(()=>"bottom"===r?{transform:[{translateY:j}]}:"fullScreen"===r?{opacity:R}:{opacity:R,transform:[{scale:C}]},[r,C,R,j]);return _jsx(RNModal,{visible:k,transparent:!0,statusBarTranslucent:!0,navigationBarTranslucent:!0,animationType:"none",onRequestClose:q,testID:b,children:_jsx(View,{ref:e=>{w.current=e,"function"==typeof t?t(e):t&&(t.current=e)},style:D.root,accessible:!1,accessibilityViewIsModal:!0,accessibilityRole:"alert",accessibilityLabel:l,children:_jsxs(ModalSafeArea,{onInsets:y,children:[_jsxs(View,{collapsable:!1,style:[StyleSheet.absoluteFill,N,{backgroundColor:_},m],children:[_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:I,accessibilityRole:"button",accessibilityLabel:"Close modal",disabled:!a}),_jsxs(Animated.View,{style:[H,P,d],onLayout:z.onLayout,pointerEvents:"auto",children:[z.active&&z.size?_jsx(SquircleFill,{width:z.size.width,height:z.size.height,radius:h.radius.xl,fill:h.colors.background.elevated}):null,u]})]}),_jsx(ToastHost,{})]})})})});Modal.displayName="Modal";const buildStyles=e=>StyleSheet.create({root:{flex:1},centeredWrapper:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:16},centeredContent:{maxWidth:"90%",width:"90%"},bottomWrapper:{flex:1,justifyContent:"flex-end"},bottomContent:{width:"100%"},fullScreenWrapper:{flex:1},fullScreenContent:{flex:1}});export{Modal};export default Modal;
1
+ "use strict";import{forwardRef,useCallback,useEffect,useMemo,useRef,useState}from"react";import{AccessibilityInfo,Animated,Dimensions,Easing,Platform,Pressable,Modal as RNModal,StyleSheet,View}from"react-native";import{usePresenceMotion}from"../../hooks/usePresenceMotion.js";import{createAnimatedValue,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{resolveHaptic,triggerHaptic}from"../../utils/hapticUtils.js";import{squircleHostRadius}from"../../utils/squircle.js";import{ModalSafeArea,useModalInsets}from"../ModalSafeArea/ModalSafeArea.js";import{SquircleFill,useSquircle}from"../SquircleFill/SquircleFill.js";import{ToastHost}from"../Toast/ToastProvider.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export const MODAL_DISMISS_GRACE_MS=300;const Modal=forwardRef((e,t)=>{const{visible:s,onRequestClose:r,presentation:i="centered",backdropOpacity:o,backdropPressClose:a=!0,animationDuration:n,accessibilityLabel:l,hardwareBackPress:u=!0,children:c,contentStyle:d,backdropStyle:m,restoreFocusRef:f,onDismissed:p,haptic:g,testID:b}=e,h=useTheme(),v=usePresenceMotion(),[S,y]=useModalInsets(),x=n??v.duration("normal"),A=Dimensions.get("window").height,M=h.components.modal,R=M?.scaleStartValue??.9,V=useRef(createAnimatedValue(R)).current,j=useRef(createAnimatedValue(0)).current,C=useRef(createAnimatedValue(A)).current,k=useRef(createAnimatedValue(0)).current,w=useRef(null),T=useRef(!1),[D,_]=useState(s),E=useMemo(()=>buildStyles(h),[h]),I=useMemo(()=>{const e=h.colors.background.overlay;if("number"!=typeof o)return e;const t=e.match(/^rgba?\(([^)]+)\)$/);if(!t)return e;const[s,r,i]=t[1].split(",").map(e=>e.trim());return`rgba(${s}, ${r}, ${i}, ${o})`},[h.colors.background.overlay,o]),N=useMemo(()=>k.interpolate({inputRange:[0,1],outputRange:[transparentOf(I),I]}),[k,I]);useEffect(()=>{s&&_(!0)},[s]),useEffect(()=>{const e=[];if(s&&D){const t=Animated.timing(k,{toValue:1,duration:v.duration("normal"),useNativeDriver:!1});if(t.start(),e.push(t),v.reduced){j.setValue(0),C.setValue(0),V.setValue(1);const t=Animated.timing(j,{toValue:1,duration:x,useNativeDriver:!0});t.start(),e.push(t)}else if("bottom"===i){j.setValue(1);const t=Animated.spring(C,{toValue:0,damping:h.motion.spring.gentle.damping,stiffness:h.motion.spring.gentle.stiffness,mass:h.motion.spring.gentle.mass,useNativeDriver:!0});t.start(),e.push(t)}else{const t=Animated.parallel([Animated.spring(V,{toValue:1,damping:h.motion.spring.gentle.damping,stiffness:h.motion.spring.gentle.stiffness,mass:h.motion.spring.gentle.mass,useNativeDriver:!0}),Animated.timing(j,{toValue:1,duration:x,useNativeDriver:!0})]);t.start(),e.push(t)}}else if(D){const t=v.duration("fast"),s=Easing.bezier(...h.motion.easing.accelerate),r=Animated.timing(j,{toValue:0,duration:t,easing:s,useNativeDriver:!0}),o=v.reduced?r:"bottom"===i?Animated.timing(C,{toValue:A,duration:t,easing:s,useNativeDriver:!0}):Animated.parallel([Animated.timing(V,{toValue:R,duration:t,easing:s,useNativeDriver:!0}),r]),a=Animated.parallel([o,Animated.timing(k,{toValue:0,duration:v.duration("normal"),useNativeDriver:!1})]);a.start(({finished:e})=>{e&&(C.setValue(A),_(!1))}),e.push(a)}return()=>e.forEach(e=>e.stop())},[s,D,i,x,V,j,k,C,A,h.motion.spring.gentle.damping,h.motion.spring.gentle.stiffness,h.motion.spring.gentle.mass,v,h.motion.easing.accelerate,R]),useEffect(()=>{if("web"===Platform.OS)return;let e,t;return s?(e=setTimeout(()=>{w.current&&AccessibilityInfo.sendAccessibilityEvent(w.current,"focus")},150),T.current=!0):T.current&&(T.current=!1,f&&f.current&&(t=setTimeout(()=>{const e=f.current;e&&AccessibilityInfo.sendAccessibilityEvent(e,"focus")},x))),()=>{e&&clearTimeout(e),t&&clearTimeout(t)}},[s,x,f]);const q=useRef(!1);useEffect(()=>{if(s)return void(q.current=!0);if(!q.current)return;if(q.current=!1,!p)return;const e=setTimeout(p,300);return()=>clearTimeout(e)},[s,p]);const P=useCallback(()=>{if(!a)return;const e=resolveHaptic(g,"selection");e&&triggerHaptic(e),r()},[a,r,g]),z=useCallback(()=>{u&&r()},[u,r]),H=useSquircle("bottom"!==i&&"fullScreen"!==i,h.radius.xl),$=useMemo(()=>"fullScreen"===i?[E.fullScreenContent,{backgroundColor:h.colors.background.elevated}]:"bottom"===i?[E.bottomContent,{backgroundColor:h.colors.background.elevated,borderTopLeftRadius:h.radius.xl,borderTopRightRadius:h.radius.xl,...smoothCorners,paddingTop:h.spacing.lg,paddingHorizontal:h.spacing.lg,paddingBottom:h.spacing.lg+S.bottom},h.shadows.xl]:[E.centeredContent,{backgroundColor:h.colors.background.elevated,borderRadius:H.active&&H.size?squircleHostRadius(H.size.width,H.size.height,h.radius.xl):h.radius.xl,...smoothCorners,padding:h.spacing.xl},h.shadows.xl],[i,h,E,S.bottom,H.active,H.size]),F=useMemo(()=>"bottom"===i?E.bottomWrapper:"fullScreen"===i?E.fullScreenWrapper:E.centeredWrapper,[i,E]),L=useMemo(()=>"bottom"===i?{opacity:j,transform:[{translateY:C}]}:"fullScreen"===i?{opacity:j}:{opacity:j,transform:[{scale:V}]},[i,V,j,C]);return _jsx(RNModal,{visible:D,transparent:!0,statusBarTranslucent:!0,navigationBarTranslucent:!0,animationType:"none",onRequestClose:z,testID:b,children:_jsx(View,{ref:e=>{w.current=e,"function"==typeof t?t(e):t&&(t.current=e)},style:E.root,accessible:!1,accessibilityViewIsModal:!0,accessibilityRole:"alert",accessibilityLabel:l,children:_jsxs(ModalSafeArea,{onInsets:y,children:[_jsxs(Animated.View,{collapsable:!1,style:[StyleSheet.absoluteFill,F,{backgroundColor:N},m],children:[_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:P,accessibilityRole:"button",accessibilityLabel:"Close modal",disabled:!a}),_jsxs(Animated.View,{style:[$,L,d],onLayout:H.onLayout,pointerEvents:"auto",children:[H.active&&H.size?_jsx(SquircleFill,{width:H.size.width,height:H.size.height,radius:h.radius.xl,fill:h.colors.background.elevated}):null,c]})]}),_jsx(ToastHost,{})]})})})});Modal.displayName="Modal";const transparentOf=e=>{const t=e.match(/^rgba?\(([^)]+)\)$/);if(!t)return"transparent";const[s,r,i]=t[1].split(",").map(e=>e.trim());return`rgba(${s}, ${r}, ${i}, 0)`},buildStyles=e=>StyleSheet.create({root:{flex:1},centeredWrapper:{flex:1,alignItems:"center",justifyContent:"center",paddingHorizontal:16},centeredContent:{maxWidth:"90%",width:"90%"},bottomWrapper:{flex:1,justifyContent:"flex-end"},bottomContent:{width:"100%"},fullScreenWrapper:{flex:1},fullScreenContent:{flex:1}});export{Modal};export default Modal;
@@ -1 +1 @@
1
- "use strict";import{forwardRef,useCallback,useEffect,useImperativeHandle,useMemo,useRef,useState}from"react";import{Animated,Easing,Pressable,StyleSheet,Text,TextInput,View}from"react-native";import{useControllableState,useReducedMotion}from"../../hooks/index.js";import{createAnimatedValue,fontFor,setNativeValue,useTheme}from"../../theme/index.js";import{resolveHaptic,triggerHaptic}from"../../utils/index.js";import{smoothCorners}from"../../utils/corners.js";import{FieldBase,FieldMessage,hasFieldText}from"../FieldBase/FieldBase.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const sizeMap={sm:{cell:36,fontSize:16,borderRadius:8,gap:8},md:{cell:48,fontSize:20,borderRadius:10,gap:10},lg:{cell:56,fontSize:24,borderRadius:12,gap:12}},sanitizeChar=(e,t)=>e?"number-pad"===t?e.replace(/\D/g,""):e:"",OTPInput=forwardRef((e,t)=>{const{value:n,defaultValue:i,onChange:r,onComplete:s,length:o=6,keyboardType:a="number-pad",autoFocus:l=!1,autoFocusDelay:u=0,disabled:c=!1,error:d,size:m="md",secure:p=!1,haptic:f,accessibilityLabel:g,style:h,cellStyle:b,textStyle:y,testID:x}=e,[v,j]=useControllableState({value:n,defaultValue:i??"",onChange:r}),C=useTheme(),S=useMemo(()=>buildStyles(C),[C]),T={...sizeMap[m],...C.components.otpInput?.[m]??{}},V=useRef([]),[R,k]=useState(-1),w=useRef(null),E=useRef(createAnimatedValue(0)).current,F=useRef(new Map),I=useMemo(()=>{const e=F.current,t=[];for(let n=0;n<o;n+=1){let i=e.get(n);i||(i=new Animated.Value(0),e.set(n,i)),t.push(i)}for(const t of Array.from(e.keys()))t>=o&&e.delete(t);return t},[o]),z=useRef(-1),A=C.components.otpInput?.shakeOnError??!1,M=useReducedMotion(),_=!0===d||hasFieldText(d);useEffect(()=>{let e;return null===w.current||!_||w.current||(!1!==f&&triggerHaptic("notificationError"),A&&!M&&(setNativeValue(E,0),e=Animated.sequence([Animated.timing(E,{toValue:1,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0}),Animated.timing(E,{toValue:-1,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0}),Animated.timing(E,{toValue:1,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0}),Animated.timing(E,{toValue:0,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0})]),e.start())),w.current=_,()=>e?.stop()},[_,E,A,f,M,C.motion.duration.instant]),useEffect(()=>{const e=z.current;if(z.current=R,e===R)return;if(-1===e&&-1===R)return;const t=[];return I.forEach((n,i)=>{const r=i===R?1:0;if(i!==R&&i!==e)return;const s=Animated.timing(n,{toValue:r,duration:C.motion.duration.fast,easing:Easing.bezier(...C.motion.easing.standard),useNativeDriver:!0});s.start(),t.push(s)}),()=>t.forEach(e=>e.stop())},[R,I,C]);const H=useCallback(e=>{const t=V.current[e];t&&t.focus()},[]);useImperativeHandle(t,()=>({focus:()=>H(0),blur:()=>{const e=V.current[R>=0?R:0];e?.blur()},clear:()=>{j(""),H(0)}}),[H,R,j]),useEffect(()=>{if(l&&!c){const e=setTimeout(()=>H(0),u);return()=>clearTimeout(e)}},[l,u,c,H]);const D=useMemo(()=>{const e=new Array(o).fill("");for(let t=0;t<Math.min(v.length,o);t+=1)e[t]=v[t]??"";return e},[v,o]),O=useCallback(e=>{const t=e.slice(0,o);t!==v&&(j(t),t.length===o&&s&&s(t))},[o,j,s,v]),P=useCallback((e,t)=>{const n=t.replace(/\u200B/g,""),i=sanitizeChar(n,a);if(!i){const t=D.slice(),n=(t[e]??"").length>0;if(t[e]="",O(t.join("").slice(0,o)),!n&&e>0){const t=D.slice();t[e-1]="",O(t.join("")),H(e-1)}return}const r=D[e]??"",s=r&&i.length>o&&i.startsWith(r)?i.slice(r.length):i;if(s.length>=o){const t=s.slice(0,o),n=v.length;if(O(t),t.length!==n){const e=resolveHaptic(f,"selection");e&&triggerHaptic(e)}return void V.current[e]?.blur()}const l=D.slice();let u=e;for(let e=0;e<i.length&&u<o;e+=1)l[u]=i[e]??"",u+=1;const c=l.join("").slice(0,o),d=v.length;if(O(c),c.length!==d){const e=resolveHaptic(f,"selection");e&&triggerHaptic(e)}const m=Math.min(u,o-1);u>=o?V.current[e]?.blur():H(m)},[D,H,a,o,f,O,v]),N=useCallback((e,t)=>{if("Backspace"!==t.nativeEvent.key)return;if(0===(D[e]??"").length){if(e>0){const t=D.slice();t[e-1]="",O(t.join("")),H(e-1)}}else{const t=D.slice();t[e]="",O(t.join(""))}},[D,H,O]),B=useCallback(e=>{k(e)},[]),W=useCallback(()=>{k(-1)},[]),L=useCallback(()=>{if(c)return;const e=D.findIndex(e=>""===e);H(-1===e?o-1:e)},[D,c,H,o]),$=g??`Enter ${o}-digit code`,q=E.interpolate({inputRange:[-1,1],outputRange:[-6,6]});return _jsxs(View,{style:h,accessible:!0,accessibilityRole:"none",accessibilityLabel:$,accessibilityValue:{text:n},accessibilityState:{disabled:c},"aria-disabled":c,testID:x,children:[_jsx(Pressable,{onPress:L,disabled:c,accessible:!1,children:_jsx(Animated.View,{style:[S.row,{columnGap:T.gap,transform:[{translateX:q}]}],children:D.map((e,t)=>{const n=R===t,i=e.length>0,r=_?C.colors.border.error:C.colors.border.focus,s=I[t];if(!s)return null;const l=p&&i?"●":e;return _jsxs(View,{style:S.cellWrapper,children:[_jsxs(FieldBase,{size:m,width:T.cell,height:T.cell,borderRadius:T.borderRadius,borderWidth:1.5,focused:n,error:_,filled:i,disabled:c,paddingHorizontal:0,paddingVertical:0,gap:0,style:b,children:[_jsx(TextInput,{ref:e=>{V.current[t]=e},value:(p&&i?"":e)||"​",onChangeText:e=>P(t,e),onKeyPress:e=>N(t,e),onFocus:()=>B(t),onBlur:W,keyboardType:a,editable:!c,selectTextOnFocus:!0,caretHidden:i,maxLength:o+1,textContentType:"oneTimeCode",autoComplete:0===t?"sms-otp":"off",importantForAutofill:0===t?"yes":"no",style:[S.input,{fontSize:T.fontSize,color:C.colors.text.primary,...fontFor(C,"semibold")},y]}),p&&i?_jsx(View,{pointerEvents:"none",style:S.maskOverlay,children:_jsx(Text,{style:[{fontSize:T.fontSize,color:C.colors.text.primary,...fontFor(C,"semibold")},y],children:l})}):null]}),_jsx(Animated.View,{style:[S.underline,{backgroundColor:r,opacity:s}]})]},`otp-cell-${t}`)})})}),_jsx(FieldMessage,{size:m,error:!0,text:d})]})});OTPInput.displayName="OTPInput";const buildStyles=e=>StyleSheet.create({row:{flexDirection:"row",alignItems:"center"},cellWrapper:{alignItems:"center"},input:{width:"100%",height:"100%",textAlign:"center",padding:0},maskOverlay:{...StyleSheet.absoluteFill,alignItems:"center",justifyContent:"center"},underline:{marginTop:4,height:2,width:"60%",borderRadius:1,...smoothCorners}});export{OTPInput};export default OTPInput;
1
+ "use strict";import{forwardRef,useCallback,useEffect,useImperativeHandle,useMemo,useRef,useState}from"react";import{Animated,Easing,Pressable,StyleSheet,Text,TextInput,View}from"react-native";import{useControllableState,useReducedMotion}from"../../hooks/index.js";import{createAnimatedValue,fontFor,setNativeValue,useTheme}from"../../theme/index.js";import{triggerHaptic}from"../../utils/index.js";import{smoothCorners}from"../../utils/corners.js";import{FieldBase,FieldMessage,hasFieldText}from"../FieldBase/FieldBase.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const sizeMap={sm:{cell:36,fontSize:16,borderRadius:8,gap:8},md:{cell:48,fontSize:20,borderRadius:10,gap:10},lg:{cell:56,fontSize:24,borderRadius:12,gap:12}},sanitizeChar=(e,t)=>e?"number-pad"===t?e.replace(/\D/g,""):e:"",OTPInput=forwardRef((e,t)=>{const{value:n,defaultValue:i,onChange:r,onComplete:s,length:a=6,keyboardType:o="number-pad",autoFocus:l=!1,autoFocusDelay:u=0,disabled:c=!1,error:d,size:m="md",secure:f=!1,haptic:p,accessibilityLabel:g,style:h,cellStyle:b,textStyle:y,testID:x}=e,[j,v]=useControllableState({value:n,defaultValue:i??"",onChange:r}),C=useTheme(),S=useMemo(()=>buildStyles(C),[C]),T={...sizeMap[m],...C.components.otpInput?.[m]??{}},V=useRef([]),[R,k]=useState(-1),w=useRef(null),E=useRef(createAnimatedValue(0)).current,F=useRef(new Map),I=useMemo(()=>{const e=F.current,t=[];for(let n=0;n<a;n+=1){let i=e.get(n);i||(i=new Animated.Value(0),e.set(n,i)),t.push(i)}for(const t of Array.from(e.keys()))t>=a&&e.delete(t);return t},[a]),z=useRef(-1),A=C.components.otpInput?.shakeOnError??!1,M=useReducedMotion(),_=!0===d||hasFieldText(d);useEffect(()=>{let e;return null===w.current||!_||w.current||(p&&triggerHaptic("notificationError"),A&&!M&&(setNativeValue(E,0),e=Animated.sequence([Animated.timing(E,{toValue:1,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0}),Animated.timing(E,{toValue:-1,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0}),Animated.timing(E,{toValue:1,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0}),Animated.timing(E,{toValue:0,duration:C.motion.duration.instant,easing:Easing.linear,useNativeDriver:!0})]),e.start())),w.current=_,()=>e?.stop()},[_,E,A,p,M,C.motion.duration.instant]),useEffect(()=>{const e=z.current;if(z.current=R,e===R)return;if(-1===e&&-1===R)return;const t=[];return I.forEach((n,i)=>{const r=i===R?1:0;if(i!==R&&i!==e)return;const s=Animated.timing(n,{toValue:r,duration:C.motion.duration.fast,easing:Easing.bezier(...C.motion.easing.standard),useNativeDriver:!0});s.start(),t.push(s)}),()=>t.forEach(e=>e.stop())},[R,I,C]);const D=useCallback(e=>{const t=V.current[e];t&&t.focus()},[]);useImperativeHandle(t,()=>({focus:()=>D(0),blur:()=>{const e=V.current[R>=0?R:0];e?.blur()},clear:()=>{v(""),D(0)}}),[D,R,v]),useEffect(()=>{if(l&&!c){const e=setTimeout(()=>D(0),u);return()=>clearTimeout(e)}},[l,u,c,D]);const O=useMemo(()=>{const e=new Array(a).fill("");for(let t=0;t<Math.min(j.length,a);t+=1)e[t]=j[t]??"";return e},[j,a]),P=useCallback(e=>{const t=e.slice(0,a);t!==j&&(v(t),t.length===a&&s&&s(t))},[a,v,s,j]),H=useCallback((e,t)=>{const n=t.replace(/\u200B/g,""),i=sanitizeChar(n,o);if(!i){const t=O.slice(),n=(t[e]??"").length>0;if(t[e]="",P(t.join("").slice(0,a)),!n&&e>0){const t=O.slice();t[e-1]="",P(t.join("")),D(e-1)}return}const r=O[e]??"",s=r&&i.length>a&&i.startsWith(r)?i.slice(r.length):i;if(s.length>=a){const t=s.slice(0,a),n=j.length;return P(t),t.length!==n&&p&&triggerHaptic(p),void V.current[e]?.blur()}const l=O.slice();let u=e;for(let e=0;e<i.length&&u<a;e+=1)l[u]=i[e]??"",u+=1;const c=l.join("").slice(0,a),d=j.length;P(c),c.length!==d&&p&&triggerHaptic(p);const m=Math.min(u,a-1);u>=a?V.current[e]?.blur():D(m)},[O,D,o,a,p,P,j]),N=useCallback((e,t)=>{if("Backspace"!==t.nativeEvent.key)return;if(0===(O[e]??"").length){if(e>0){const t=O.slice();t[e-1]="",P(t.join("")),D(e-1)}}else{const t=O.slice();t[e]="",P(t.join(""))}},[O,D,P]),B=useCallback(e=>{k(e)},[]),W=useCallback(()=>{k(-1)},[]),L=useCallback(()=>{if(c)return;const e=O.findIndex(e=>""===e);D(-1===e?a-1:e)},[O,c,D,a]),$=g??`Enter ${a}-digit code`,q=E.interpolate({inputRange:[-1,1],outputRange:[-6,6]});return _jsxs(View,{style:h,accessible:!0,accessibilityRole:"none",accessibilityLabel:$,accessibilityValue:{text:n},accessibilityState:{disabled:c},"aria-disabled":c,testID:x,children:[_jsx(Pressable,{onPress:L,disabled:c,accessible:!1,children:_jsx(Animated.View,{style:[S.row,{columnGap:T.gap,transform:[{translateX:q}]}],children:O.map((e,t)=>{const n=R===t,i=e.length>0,r=_?C.colors.border.error:C.colors.border.focus,s=I[t];if(!s)return null;const l=f&&i?"●":e;return _jsxs(View,{style:S.cellWrapper,children:[_jsxs(FieldBase,{size:m,width:T.cell,height:T.cell,borderRadius:T.borderRadius,borderWidth:1.5,focused:n,error:_,filled:i,disabled:c,paddingHorizontal:0,paddingVertical:0,gap:0,style:b,children:[_jsx(TextInput,{ref:e=>{V.current[t]=e},value:(f&&i?"":e)||"​",onChangeText:e=>H(t,e),onKeyPress:e=>N(t,e),onFocus:()=>B(t),onBlur:W,keyboardType:o,editable:!c,selectTextOnFocus:!0,caretHidden:i,maxLength:a+1,textContentType:"oneTimeCode",autoComplete:0===t?"sms-otp":"off",importantForAutofill:0===t?"yes":"no",style:[S.input,{fontSize:T.fontSize,color:C.colors.text.primary,...fontFor(C,"semibold")},y]}),f&&i?_jsx(View,{pointerEvents:"none",style:S.maskOverlay,children:_jsx(Text,{style:[{fontSize:T.fontSize,color:C.colors.text.primary,...fontFor(C,"semibold")},y],children:l})}):null]}),_jsx(Animated.View,{style:[S.underline,{backgroundColor:r,opacity:s}]})]},`otp-cell-${t}`)})})}),_jsx(FieldMessage,{size:m,error:!0,text:d})]})});OTPInput.displayName="OTPInput";const buildStyles=e=>StyleSheet.create({row:{flexDirection:"row",alignItems:"center"},cellWrapper:{alignItems:"center"},input:{width:"100%",height:"100%",textAlign:"center",padding:0},maskOverlay:{...StyleSheet.absoluteFill,alignItems:"center",justifyContent:"center"},underline:{marginTop:4,height:2,width:"60%",borderRadius:1,...smoothCorners}});export{OTPInput};export default OTPInput;
@@ -1 +1 @@
1
- "use strict";import{useCallback,useEffect,useMemo,useRef,useState}from"react";import{Animated,Easing,Pressable,ScrollView,StyleSheet,View}from"react-native";import{useSafeAreaInsets}from"react-native-safe-area-context";import{useReducedMotion}from"../../hooks/useReducedMotion.js";import{createAnimatedValue,useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{smoothCorners}from"../../utils/corners.js";import{Button}from"../Button/index.js";import{Carousel}from"../Carousel/index.js";import{Text}from"../Text/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const ONBOARDING_MAX_PAGES=6,CONTROL_HEIGHT=44,DOT_SIZE=8,DOT_ACTIVE_WIDTH=24,defaultStep=(e,t)=>`Step ${e} of ${t}`,OnboardingPager=({pages:e,onDone:t,onSkip:o,doneLabel:n="Get started",labels:s,safeArea:i=!0,haptic:a,testID:r})=>{const l=useTheme(),c=useSafeAreaInsets(),d=useReducedMotion(),u=useMemo(()=>buildStyles(l),[l]),m=useMemo(()=>e.slice(0,6),[e]),p=m.length,g=s?.step??defaultStep,b=useRef(null),[x,f]=useState(0),y=x>=p-1,h=useCallback(e=>{e<0||e>=p||b.current?.scrollTo(e,!d)},[p,d]),j=useCallback(e=>h(x+e),[h,x]),S=useCallback(()=>{y?t():h(x+1)},[y,t,h,x]),_=useRef(x);useEffect(()=>{if(_.current===x)return;_.current=x;const e=m[x];e&&announce(`${g(x+1,p)}, ${e.title}`)},[x,m,p,g]);const C=useCallback((e,t)=>_jsx(ScrollView,{style:u.page,contentContainerStyle:u.pageContent,showsVerticalScrollIndicator:!1,bounces:!1,children:_jsxs(View,{accessible:!0,accessibilityLabel:`${g(t+1,p)}, ${e.title}. ${e.body}`,style:u.pageGroup,children:[e.art?_jsx(View,{style:u.art,children:e.art}):null,_jsx(Text,{variant:"h2",align:"center",children:e.title}),_jsx(Text,{variant:"body",color:"secondary",align:"center",children:e.body})]})}),[u,g,p]);return 0===p?null:_jsxs(View,{style:[u.root,i?{paddingTop:c.top,paddingBottom:c.bottom}:null],testID:r,children:[_jsx(View,{style:u.skipRow,children:_jsx(Button,{title:s?.skip??"Skip",variant:"ghost",tone:"neutral",hitSlop:{top:2,bottom:2,left:8,right:8},haptic:a,onPress:o,testID:r?`${r}-skip`:void 0})}),_jsx(Carousel,{ref:b,data:m,renderItem:C,keyExtractor:e=>e.key,onIndexChange:f,showPagination:!1,containerStyle:u.carousel,testID:r?`${r}-pages`:void 0}),_jsxs(View,{style:u.footer,children:[p>1?_jsx(PageControl,{keys:m.map(e=>e.key),index:x,label:s?.pageControl??"Page",valueText:g(x+1,p),reduceMotion:d,theme:l,onStep:j,testID:r?`${r}-dots`:void 0}):null,_jsx(Button,{title:y?n:s?.next??"Next",size:"lg",fullWidth:!0,haptic:a,onPress:S,testID:r?`${r}-next`:void 0})]})]})};OnboardingPager.displayName="OnboardingPager";const PageControl=({keys:e,index:t,label:o,valueText:n,reduceMotion:s,theme:i,onStep:a,testID:r})=>{const l=useCallback(e=>{"increment"===e.nativeEvent.actionName?a(1):"decrement"===e.nativeEvent.actionName&&a(-1)},[a]);return _jsxs(View,{accessible:!0,accessibilityRole:"adjustable",accessibilityLabel:o,accessibilityValue:{min:0,max:e.length-1,now:t,text:n},accessibilityActions:[{name:"increment"},{name:"decrement"}],onAccessibilityAction:l,style:controlStyles.control,testID:r,children:[_jsx(View,{style:controlStyles.dots,pointerEvents:"none",children:e.map((e,o)=>_jsx(Dot,{active:o===t,reduceMotion:s,theme:i},e))}),_jsx(Pressable,{accessible:!1,importantForAccessibility:"no",style:controlStyles.back,onPress:()=>a(-1),testID:r?`${r}-back`:void 0}),_jsx(Pressable,{accessible:!1,importantForAccessibility:"no",style:controlStyles.forward,onPress:()=>a(1),testID:r?`${r}-forward`:void 0})]})},Dot=({active:e,reduceMotion:t,theme:o})=>{const n=useRef(createAnimatedValue(e?1:0)).current;return useEffect(()=>{const s=Animated.timing(n,{toValue:e?1:0,duration:t?0:o.motion.duration.normal,easing:Easing.bezier(...o.motion.easing.standard),useNativeDriver:!1});return s.start(),()=>s.stop()},[e,t,n,o]),_jsx(Animated.View,{style:{width:n.interpolate({inputRange:[0,1],outputRange:[8,24]}),height:8,marginHorizontal:o.spacing.xs,borderRadius:4,...smoothCorners,backgroundColor:n.interpolate({inputRange:[0,1],outputRange:[o.colors.border.primary,o.colors.primary]})}})},controlStyles=StyleSheet.create({control:{alignSelf:"center",height:44,minWidth:88,alignItems:"center",justifyContent:"center"},dots:{flexDirection:"row",alignItems:"center"},back:{position:"absolute",top:0,bottom:0,start:0,width:"50%"},forward:{position:"absolute",top:0,bottom:0,end:0,width:"50%"}}),buildStyles=e=>StyleSheet.create({root:{flex:1,backgroundColor:e.colors.background.primary},skipRow:{minHeight:44,paddingHorizontal:e.spacing.lg,alignItems:"flex-end",justifyContent:"center"},carousel:{flex:1},page:{flex:1},pageContent:{flexGrow:1,justifyContent:"center",paddingHorizontal:e.spacing.xl,paddingVertical:e.spacing.lg},pageGroup:{alignItems:"center",gap:e.spacing.md},art:{alignItems:"center",marginBottom:e.spacing.xl},footer:{paddingHorizontal:e.spacing.lg,paddingBottom:e.spacing.lg,gap:e.spacing.sm}});export{OnboardingPager};export default OnboardingPager;
1
+ "use strict";import{useCallback,useEffect,useMemo,useRef,useState}from"react";import{Animated,Easing,Pressable,ScrollView,StyleSheet,View}from"react-native";import{useSafeAreaInsets}from"react-native-safe-area-context";import{useReducedMotion}from"../../hooks/useReducedMotion.js";import{createAnimatedValue,useTheme}from"../../theme/index.js";import{announce}from"../../utils/announce.js";import{smoothCorners}from"../../utils/corners.js";import{Button}from"../Button/index.js";import{Carousel}from"../Carousel/index.js";import{Text}from"../Text/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const ONBOARDING_MAX_PAGES=6,CONTROL_HEIGHT=44,DOT_SIZE=8,DOT_ACTIVE_WIDTH=24,defaultStep=(e,t)=>`Step ${e} of ${t}`,OnboardingPager=({pages:e,onDone:t,onSkip:o,doneLabel:n="Get started",labels:s,safeArea:i=!0,haptic:a="selection",testID:r})=>{const l=useTheme(),c=useSafeAreaInsets(),d=useReducedMotion(),u=useMemo(()=>buildStyles(l),[l]),m=useMemo(()=>e.slice(0,6),[e]),p=m.length,g=s?.step??defaultStep,b=useRef(null),[x,f]=useState(0),y=x>=p-1,h=useCallback(e=>{e<0||e>=p||b.current?.scrollTo(e,!d)},[p,d]),j=useCallback(e=>h(x+e),[h,x]),S=useCallback(()=>{y?t():h(x+1)},[y,t,h,x]),_=useRef(x);useEffect(()=>{if(_.current===x)return;_.current=x;const e=m[x];e&&announce(`${g(x+1,p)}, ${e.title}`)},[x,m,p,g]);const C=useCallback((e,t)=>_jsx(ScrollView,{style:u.page,contentContainerStyle:u.pageContent,showsVerticalScrollIndicator:!1,bounces:!1,children:_jsxs(View,{accessible:!0,accessibilityLabel:`${g(t+1,p)}, ${e.title}. ${e.body}`,style:u.pageGroup,children:[e.art?_jsx(View,{style:u.art,children:e.art}):null,_jsx(Text,{variant:"h2",align:"center",children:e.title}),_jsx(Text,{variant:"body",color:"secondary",align:"center",children:e.body})]})}),[u,g,p]);return 0===p?null:_jsxs(View,{style:[u.root,i?{paddingTop:c.top,paddingBottom:c.bottom}:null],testID:r,children:[_jsx(View,{style:u.skipRow,children:_jsx(Button,{title:s?.skip??"Skip",variant:"ghost",tone:"neutral",hitSlop:{top:2,bottom:2,left:8,right:8},haptic:a,onPress:o,testID:r?`${r}-skip`:void 0})}),_jsx(Carousel,{ref:b,data:m,renderItem:C,keyExtractor:e=>e.key,onIndexChange:f,showPagination:!1,containerStyle:u.carousel,testID:r?`${r}-pages`:void 0}),_jsxs(View,{style:u.footer,children:[p>1?_jsx(PageControl,{keys:m.map(e=>e.key),index:x,label:s?.pageControl??"Page",valueText:g(x+1,p),reduceMotion:d,theme:l,onStep:j,testID:r?`${r}-dots`:void 0}):null,_jsx(Button,{title:y?n:s?.next??"Next",size:"lg",fullWidth:!0,haptic:a,onPress:S,testID:r?`${r}-next`:void 0})]})]})};OnboardingPager.displayName="OnboardingPager";const PageControl=({keys:e,index:t,label:o,valueText:n,reduceMotion:s,theme:i,onStep:a,testID:r})=>{const l=useCallback(e=>{"increment"===e.nativeEvent.actionName?a(1):"decrement"===e.nativeEvent.actionName&&a(-1)},[a]);return _jsxs(View,{accessible:!0,accessibilityRole:"adjustable",accessibilityLabel:o,accessibilityValue:{min:0,max:e.length-1,now:t,text:n},accessibilityActions:[{name:"increment"},{name:"decrement"}],onAccessibilityAction:l,style:controlStyles.control,testID:r,children:[_jsx(View,{style:controlStyles.dots,pointerEvents:"none",children:e.map((e,o)=>_jsx(Dot,{active:o===t,reduceMotion:s,theme:i},e))}),_jsx(Pressable,{accessible:!1,importantForAccessibility:"no",style:controlStyles.back,onPress:()=>a(-1),testID:r?`${r}-back`:void 0}),_jsx(Pressable,{accessible:!1,importantForAccessibility:"no",style:controlStyles.forward,onPress:()=>a(1),testID:r?`${r}-forward`:void 0})]})},Dot=({active:e,reduceMotion:t,theme:o})=>{const n=useRef(createAnimatedValue(e?1:0)).current;return useEffect(()=>{const s=Animated.timing(n,{toValue:e?1:0,duration:t?0:o.motion.duration.normal,easing:Easing.bezier(...o.motion.easing.standard),useNativeDriver:!1});return s.start(),()=>s.stop()},[e,t,n,o]),_jsx(Animated.View,{style:{width:n.interpolate({inputRange:[0,1],outputRange:[8,24]}),height:8,marginHorizontal:o.spacing.xs,borderRadius:4,...smoothCorners,backgroundColor:n.interpolate({inputRange:[0,1],outputRange:[o.colors.border.primary,o.colors.primary]})}})},controlStyles=StyleSheet.create({control:{alignSelf:"center",height:44,minWidth:88,alignItems:"center",justifyContent:"center"},dots:{flexDirection:"row",alignItems:"center"},back:{position:"absolute",top:0,bottom:0,start:0,width:"50%"},forward:{position:"absolute",top:0,bottom:0,end:0,width:"50%"}}),buildStyles=e=>StyleSheet.create({root:{flex:1,backgroundColor:e.colors.background.primary},skipRow:{minHeight:44,paddingHorizontal:e.spacing.lg,alignItems:"flex-end",justifyContent:"center"},carousel:{flex:1},page:{flex:1},pageContent:{flexGrow:1,justifyContent:"center",paddingHorizontal:e.spacing.xl,paddingVertical:e.spacing.lg},pageGroup:{alignItems:"center",gap:e.spacing.md},art:{alignItems:"center",marginBottom:e.spacing.xl},footer:{paddingHorizontal:e.spacing.lg,paddingBottom:e.spacing.lg,gap:e.spacing.sm}});export{OnboardingPager};export default OnboardingPager;
@@ -1 +1 @@
1
- "use strict";import{useCallback,useEffect,useMemo,useRef,useState}from"react";import{Animated,Dimensions,Easing,FlatList,Modal,Platform,Pressable,StatusBar,StyleSheet,Text,TextInput,View}from"react-native";import{Gesture,GestureDetector,GestureHandlerRootView}from"react-native-gesture-handler";import{useKeyboardState}from"react-native-keyboard-controller";import{useDragToDismiss}from"../../hooks/useDragToDismiss.js";import{createAnimatedValue,setNativeValue,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{defaultIcons}from"../AppIcon/defaultIcons.js";import{ModalSafeArea,useModalInsets}from"../ModalSafeArea/ModalSafeArea.js";import{ToastHost}from"../Toast/ToastProvider.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const SEARCH_ICON_SIZE=18;export const OptionSheet=e=>{const{open:t,onClose:o,onAfterClose:i,onOpenChange:s,title:r,options:n,sections:a,renderSectionHeader:l,renderOption:c,alphabetIndex:d=!1,searchPlaceholder:p="Search…",emptyText:u="No options",labelOf:h,getValue:m,disabledOf:g,destructiveOf:f,descriptionOf:y,iconOf:b,isSelected:x,onSelect:S,multi:T=!1,searchable:j=!1,searchSelectionColor:C,accessibilityLabel:w,optionStyle:_,selectedOptionStyle:R,optionTextStyle:V,selectedOptionTextStyle:k,testID:I}=e,v=useTheme(),[z,D]=useModalInsets(),L=useMemo(()=>buildStyles(v),[v]),[P,M]=useState(""),H=Dimensions.get("window").height,W=Math.round(.7*H),[A,O]=useState(t),B=useRef(createAnimatedValue(0)).current,E=useRef(createAnimatedValue(W)).current,F=useRef(createAnimatedValue(0)).current,N=useMemo(()=>Animated.add(E,F),[E,F]);useEffect(()=>{t&&O(!0)},[t]);const G=useRef(s);G.current=s;const $=useRef(!1);useEffect(()=>{$.current!==t&&($.current=t,G.current?.(t))},[t]);const J=useRef(i);J.current=i;const K=useRef(A);useEffect(()=>{K.current&&!A&&"ios"!==Platform.OS&&J.current?.(),K.current=A},[A]),useEffect(()=>{if(!A)return;t&&setNativeValue(F,0);const e=t?Animated.parallel([Animated.timing(B,{toValue:1,duration:v.motion.duration.fast,easing:Easing.bezier(...v.motion.easing.standard),useNativeDriver:!1}),Animated.spring(E,{toValue:0,damping:v.motion.spring.snappy.damping,stiffness:v.motion.spring.snappy.stiffness,mass:v.motion.spring.snappy.mass,useNativeDriver:!0})]):Animated.parallel([Animated.timing(B,{toValue:0,duration:v.motion.duration.fast,easing:Easing.bezier(...v.motion.easing.standard),useNativeDriver:!1}),Animated.timing(E,{toValue:W,duration:v.motion.duration.fast,easing:Easing.bezier(...v.motion.easing.accelerate),useNativeDriver:!0})]);return e.start(({finished:e})=>{e&&!t&&O(!1)}),()=>e.stop()},[t,A,B,E,F,W,v.motion.duration.fast,v.motion.easing.standard,v.motion.easing.accelerate,v.motion.spring.snappy]);const{handleGesture:U}=useDragToDismiss({drag:F,travel:W,onDismiss:o}),Y=useMemo(()=>Gesture.Native(),[]),[Z,q]=useState(0),Q=useKeyboardState(e=>e.height),X=A?Math.max(0,Math.round(Q)):0,ee=Math.max(z.top,StatusBar.currentHeight??0)+v.spacing.sm,te=X>0,oe=te?Math.max(0,Math.min(W,(Z>0?Z:H)-X-ee)):W;useEffect(()=>{t||M("")},[t]);const ie=useMemo(()=>{const e=j?P.trim().toLowerCase():"",matches=t=>0===e.length||h(t).toLowerCase().includes(e)||(y(t)??"").toLowerCase().includes(e);if(!a)return n.filter(matches).map(e=>({kind:"option",option:e}));const t=[];return a.forEach((e,o)=>{const i=e.options.filter(matches);if(0!==i.length){t.push({kind:"header",title:e.title});for(const e of i)t.push({kind:"option",option:e,section:o})}}),t},[j,P,n,a,h,y]),se=useCallback(()=>{o()},[o]),re=useRef(null),ne=useMemo(()=>{const e=new Map;if(!d)return e;let t=0;if(a)for(let e=ie.length-1;e>=0;e-=1)if("header"===ie[e].kind){t=e+1;break}for(let o=t;o<ie.length;o+=1){const t=ie[o];if("option"!==t.kind)continue;const i=h(t.option).trim().charAt(0).toUpperCase(),s=/^[A-Z]$/.test(i)?i:"#";e.has(s)||e.set(s,o)}return e},[d,ie,a,h]),ae=d&&ne.size>0&&0===P.trim().length,le=useMemo(()=>[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ",...ne.has("#")?["#"]:[]],[ne]),ce=useCallback(e=>{const t=ne.get(e);void 0!==t&&re.current?.scrollToIndex({index:t,animated:!0,viewPosition:0})},[ne]),de=useRef(null),pe=useCallback(()=>{null!==de.current&&(clearTimeout(de.current),de.current=null)},[]),ue=useCallback(e=>{re.current?.scrollToOffset({offset:e.averageItemLength*e.index,animated:!1}),pe(),de.current=setTimeout(()=>{de.current=null,re.current?.scrollToIndex({index:e.index,animated:!0,viewPosition:0})},50)},[pe]);useEffect(()=>(A||pe(),pe),[A,pe]);return _jsx(Modal,{visible:A,transparent:!0,animationType:"none",onRequestClose:se,onDismiss:()=>J.current?.(),statusBarTranslucent:!0,navigationBarTranslucent:!0,children:_jsx(ModalSafeArea,{onInsets:D,children:_jsxs(GestureHandlerRootView,{collapsable:!1,onLayout:e=>q(e.nativeEvent.layout.height),style:[StyleSheet.absoluteFill,{backgroundColor:v.colors.background.overlay}],children:[_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:se,accessibilityRole:"button",accessibilityLabel:"Close picker"}),_jsxs(Animated.View,{testID:I,accessibilityViewIsModal:!0,accessibilityLabel:w??r??"Options",style:[L.sheet,{maxHeight:oe,bottom:X,paddingBottom:te?16:z.bottom+16,backgroundColor:v.colors.background.elevated,borderTopLeftRadius:v.radius.xl,borderTopRightRadius:v.radius.xl,...smoothCorners,transform:[{translateY:N}],...v.shadows.xl}],children:[_jsx(GestureDetector,{gesture:U,children:_jsxs(View,{children:[_jsx(View,{style:L.sheetHandleRow,children:_jsx(View,{style:[L.sheetHandle,{backgroundColor:v.components.select?.handleColor??v.components.bottomSheet?.handleColor??v.colors.border.primary}]})}),r?_jsx(Text,{style:[L.sheetTitle,{color:v.colors.text.primary,fontSize:v.typography.fontSize.lg,fontWeight:v.typography.fontWeight.semibold,paddingHorizontal:v.spacing.lg,marginBottom:v.spacing.sm}],children:r}):null]})}),j?_jsx(View,{style:[L.searchWrap,{marginHorizontal:v.spacing.lg,marginBottom:v.spacing.sm}],children:_jsxs(View,{style:[L.searchBox,{backgroundColor:v.colors.background.secondary,borderColor:v.colors.border.primary,borderRadius:v.radius.md,...smoothCorners,paddingHorizontal:v.spacing.md,gap:v.spacing.sm}],children:[(v.icons?.search??defaultIcons.search)({size:18,color:v.colors.text.tertiary}),_jsx(TextInput,{value:P,onChangeText:M,placeholder:p,placeholderTextColor:v.colors.text.tertiary,selectionColor:C??v.colors.border.focus,accessibilityLabel:"Search options",style:[L.searchInput,{color:v.colors.text.primary,fontSize:v.typography.fontSize.base,paddingVertical:v.spacing.sm}]}),P.length>0?_jsx(Pressable,{onPress:()=>M(""),hitSlop:8,accessibilityRole:"button",accessibilityLabel:"Clear search",children:(v.icons?.close??defaultIcons.close)({size:18,color:v.colors.text.secondary})}):null]})}):null,_jsxs(View,{style:[L.listWrap,ae?L.listRow:null],children:[_jsx(GestureDetector,{gesture:Y,children:_jsx(FlatList,{ref:re,data:ie,keyExtractor:e=>"header"===e.kind?`h:${e.title}`:`o:${e.section??""}:${String(m(e.option))}`,renderItem:({item:e})=>{if("header"===e.kind)return _jsx(View,{accessible:!0,accessibilityRole:"header",style:[L.sectionHeader,{paddingHorizontal:v.spacing.lg,paddingTop:v.spacing.md}],children:l?l(e.title):_jsx(Text,{style:[L.sectionTitle,{color:v.colors.text.tertiary,fontSize:v.typography.fontSize.xs,fontWeight:v.typography.fontWeight.semibold}],children:e.title.toUpperCase()})});const t=e.option,o=h(t),i=m(t),s=y(t),r=b(t),n=x(i),a=g(t),d=f?.(t)??!1;return _jsxs(Pressable,{onPress:()=>S(t),disabled:a,android_ripple:{color:v.colors.surface.pressed,borderless:!1},accessibilityRole:"button",accessibilityLabel:o,accessibilityState:{selected:n,disabled:a},"aria-selected":n,"aria-disabled":a,style:({pressed:e})=>[L.optionRow,{backgroundColor:n?v.colors.surface.selected:e?v.colors.surface.pressed:"transparent",opacity:a?.5:1,paddingHorizontal:v.spacing.lg,paddingVertical:v.spacing.md},_,n?R:null],children:[c?_jsx(View,{style:L.optionTextWrap,children:c(t,{selected:n,disabled:a})}):_jsxs(_Fragment,{children:[r?_jsx(View,{style:L.optionIcon,children:r}):null,_jsxs(View,{style:L.optionTextWrap,children:[_jsx(Text,{style:[L.optionLabel,{color:d?v.colors.toneText.error:n?v.colors.primary:v.colors.text.primary,fontSize:v.typography.fontSize.base,fontWeight:n?v.typography.fontWeight.semibold:v.typography.fontWeight.medium},V,n?k:null],children:o}),s?_jsx(Text,{style:[L.optionDescription,{color:v.colors.text.tertiary,fontSize:v.typography.fontSize.sm}],numberOfLines:2,children:s}):null]})]}),T?_jsx(View,{style:[L.checkbox,{borderColor:n?v.colors.primary:v.colors.border.primary,backgroundColor:n?v.colors.primary:"transparent"}],children:n?_jsx(View,{style:L.checkboxTick}):null}):n?"icon"===v.components.optionSheet?.selectedMarker?_jsx(View,{style:L.singleSelectedIcon,children:(v.icons?.selectedTick??defaultIcons.selectedTick)({size:20,color:v.colors.primary})}):_jsx(View,{style:[L.singleSelectedDot,{backgroundColor:v.colors.primary}]}):null]})},onScrollToIndexFailed:ue,overScrollMode:"never",bounces:!1,keyboardShouldPersistTaps:"handled",showsVerticalScrollIndicator:!ae,style:ae?L.listBesideRail:null,ListEmptyComponent:_jsx(Text,{style:[L.empty,{color:v.colors.text.tertiary,fontSize:v.typography.fontSize.sm,paddingVertical:v.spacing.xl}],children:u})})}),ae?_jsx(View,{style:[L.rail,{paddingRight:v.spacing.xs}],accessibilityRole:"list",accessibilityLabel:"Jump to letter",testID:"option-sheet-alphabet",children:le.map(e=>{const t=ne.has(e);return _jsx(Pressable,{onPress:()=>ce(e),disabled:!t,hitSlop:{left:8,right:8},accessibilityRole:"button",accessibilityLabel:`Jump to ${e}`,accessibilityState:{disabled:!t},"aria-disabled":!t,style:L.railLetter,children:_jsx(Text,{style:[L.railLetterText,{color:t?v.colors.primary:v.colors.text.tertiary,fontSize:v.typography.fontSize.xs,fontWeight:v.typography.fontWeight.semibold,opacity:t?1:.45}],children:e})},e)})}):null]}),T?_jsx(View,{style:[L.sheetFooter,{borderTopColor:v.colors.border.secondary,paddingHorizontal:v.spacing.lg,paddingVertical:v.spacing.md}],children:_jsx(Pressable,{onPress:se,accessibilityRole:"button",accessibilityLabel:"Done",style:({pressed:e})=>[L.doneButton,{backgroundColor:e?v.colors.primaryPressed:v.colors.primary,borderRadius:v.radius.md,...smoothCorners,paddingVertical:v.spacing.sm,paddingHorizontal:v.spacing.lg}],children:_jsx(Text,{style:{color:v.colors.onPrimary,fontSize:v.typography.fontSize.base,fontWeight:v.typography.fontWeight.semibold},children:"Done"})})}):null]}),_jsx(ToastHost,{})]})})})};OptionSheet.displayName="OptionSheet";const buildStyles=e=>StyleSheet.create({sheet:{position:"absolute",left:0,right:0,bottom:0,paddingBottom:16,overflow:"hidden"},sheetHandleRow:{alignItems:"center",paddingTop:10,paddingBottom:8},sheetHandle:{width:36,height:4,borderRadius:2,...smoothCorners},sheetTitle:{includeFontPadding:!1},searchWrap:{width:"auto"},searchBox:{flexDirection:"row",alignItems:"center",borderWidth:1},searchInput:{flex:1,includeFontPadding:!1},optionRow:{flexDirection:"row",alignItems:"center"},sectionHeader:{paddingBottom:4},listWrap:{flexShrink:1},listRow:{flexDirection:"row"},listBesideRail:{flex:1},rail:{justifyContent:"space-between",alignItems:"center",alignSelf:"stretch",paddingVertical:4},railLetter:{paddingHorizontal:4,minHeight:14,justifyContent:"center"},railLetterText:{includeFontPadding:!1,lineHeight:14},sectionTitle:{includeFontPadding:!1,letterSpacing:.6},optionIcon:{marginRight:12},optionTextWrap:{flex:1},optionLabel:{includeFontPadding:!1},optionDescription:{includeFontPadding:!1,marginTop:2},checkbox:{width:22,height:22,borderRadius:6,...smoothCorners,borderWidth:2,alignItems:"center",justifyContent:"center",marginLeft:12},checkboxTick:{width:10,height:6,borderLeftWidth:2,borderBottomWidth:2,borderColor:e.colors.onPrimary,transform:[{rotate:"-45deg"},{translateY:-1}]},singleSelectedDot:{width:8,height:8,borderRadius:4,...smoothCorners,marginLeft:12},singleSelectedIcon:{marginLeft:12},empty:{textAlign:"center"},sheetFooter:{borderTopWidth:StyleSheet.hairlineWidth,alignItems:"flex-end"},doneButton:{alignSelf:"flex-end"}});export default OptionSheet;
1
+ "use strict";import{useCallback,useEffect,useMemo,useRef,useState}from"react";import{Animated,Dimensions,Easing,FlatList,Modal,Platform,Pressable,StatusBar,StyleSheet,Text,TextInput,View}from"react-native";import{Gesture,GestureDetector,GestureHandlerRootView}from"react-native-gesture-handler";import{useKeyboardState}from"react-native-keyboard-controller";import{useDragToDismiss}from"../../hooks/useDragToDismiss.js";import{usePresenceMotion}from"../../hooks/usePresenceMotion.js";import{createAnimatedValue,setNativeValue,useTheme}from"../../theme/index.js";import{smoothCorners}from"../../utils/corners.js";import{defaultIcons}from"../AppIcon/defaultIcons.js";import{ModalSafeArea,useModalInsets}from"../ModalSafeArea/ModalSafeArea.js";import{ToastHost}from"../Toast/ToastProvider.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const AnimatedGestureRoot=Animated.createAnimatedComponent(GestureHandlerRootView),SEARCH_ICON_SIZE=18;export const OptionSheet=e=>{const{open:t,onClose:o,onAfterClose:r,onOpenChange:i,title:s,options:n,sections:a,renderSectionHeader:l,renderOption:c,alphabetIndex:d=!1,searchPlaceholder:u="Search…",emptyText:p="No options",labelOf:m,getValue:h,disabledOf:g,destructiveOf:y,descriptionOf:f,iconOf:b,isSelected:x,onSelect:S,multi:T=!1,searchable:j=!1,searchSelectionColor:C,accessibilityLabel:w,optionStyle:R,selectedOptionStyle:_,optionTextStyle:V,selectedOptionTextStyle:k,testID:I}=e,v=useTheme(),z=usePresenceMotion(),[M,D]=useModalInsets(),P=useMemo(()=>buildStyles(v),[v]),[A,L]=useState(""),H=Dimensions.get("window").height,W=Math.round(.7*H),[O,E]=useState(t),B=useRef(createAnimatedValue(0)).current,F=useRef(createAnimatedValue(W)).current,N=useRef(createAnimatedValue(0)).current,G=useMemo(()=>z.reduced?N:Animated.add(F,N),[z.reduced,F,N]),$=useMemo(()=>z.reduced?F.interpolate({inputRange:[0,W],outputRange:[1,0],extrapolate:"clamp"}):1,[z.reduced,F,W]),{handleGesture:J,opacity:K}=useDragToDismiss({drag:N,travel:W,onDismiss:o}),U=useMemo(()=>Animated.multiply($,K),[$,K]),Y=useMemo(()=>{const e=v.colors.background.overlay;return B.interpolate({inputRange:[0,1],outputRange:[transparentOf(e),e]})},[B,v.colors.background.overlay]);useEffect(()=>{t&&E(!0)},[t]);const Z=useRef(i);Z.current=i;const q=useRef(!1);useEffect(()=>{q.current!==t&&(q.current=t,Z.current?.(t))},[t]);const Q=useRef(r);Q.current=r;const X=useRef(O);useEffect(()=>{X.current&&!O&&"ios"!==Platform.OS&&Q.current?.(),X.current=O},[O]),useEffect(()=>{if(!O)return;t&&(setNativeValue(N,0),setNativeValue(K,1));const e=t?Animated.parallel([Animated.timing(B,{toValue:1,duration:z.duration("normal"),easing:Easing.bezier(...v.motion.easing.standard),useNativeDriver:!1}),z.reduced?Animated.timing(F,{toValue:0,duration:z.duration("normal"),easing:Easing.bezier(...v.motion.easing.standard),useNativeDriver:!0}):Animated.spring(F,{toValue:0,damping:v.motion.spring.snappy.damping,stiffness:v.motion.spring.snappy.stiffness,mass:v.motion.spring.snappy.mass,useNativeDriver:!0})]):Animated.parallel([Animated.timing(B,{toValue:0,duration:z.duration("normal"),easing:Easing.bezier(...v.motion.easing.standard),useNativeDriver:!1}),Animated.timing(F,{toValue:W,duration:z.duration("fast"),easing:Easing.bezier(...v.motion.easing.accelerate),useNativeDriver:!0})]);return e.start(({finished:e})=>{e&&!t&&E(!1)}),()=>e.stop()},[t,O,B,F,N,K,W,z,v.motion.easing.standard,v.motion.easing.accelerate,v.motion.spring.snappy]);const ee=useMemo(()=>Gesture.Native(),[]),[te,oe]=useState(0),re=useKeyboardState(e=>e.height),ie=O?Math.max(0,Math.round(re)):0,se=Math.max(M.top,StatusBar.currentHeight??0)+v.spacing.sm,ne=ie>0,ae=ne?Math.max(0,Math.min(W,(te>0?te:H)-ie-se)):W;useEffect(()=>{t||L("")},[t]);const le=useMemo(()=>{const e=j?A.trim().toLowerCase():"",matches=t=>0===e.length||m(t).toLowerCase().includes(e)||(f(t)??"").toLowerCase().includes(e);if(!a)return n.filter(matches).map(e=>({kind:"option",option:e}));const t=[];return a.forEach((e,o)=>{const r=e.options.filter(matches);if(0!==r.length){t.push({kind:"header",title:e.title});for(const e of r)t.push({kind:"option",option:e,section:o})}}),t},[j,A,n,a,m,f]),ce=useCallback(()=>{o()},[o]),de=useRef(null),ue=useMemo(()=>{const e=new Map;if(!d)return e;let t=0;if(a)for(let e=le.length-1;e>=0;e-=1)if("header"===le[e].kind){t=e+1;break}for(let o=t;o<le.length;o+=1){const t=le[o];if("option"!==t.kind)continue;const r=m(t.option).trim().charAt(0).toUpperCase(),i=/^[A-Z]$/.test(r)?r:"#";e.has(i)||e.set(i,o)}return e},[d,le,a,m]),pe=d&&ue.size>0&&0===A.trim().length,me=useMemo(()=>[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ",...ue.has("#")?["#"]:[]],[ue]),he=useCallback(e=>{const t=ue.get(e);void 0!==t&&de.current?.scrollToIndex({index:t,animated:!0,viewPosition:0})},[ue]),ge=useRef(null),ye=useCallback(()=>{null!==ge.current&&(clearTimeout(ge.current),ge.current=null)},[]),fe=useCallback(e=>{de.current?.scrollToOffset({offset:e.averageItemLength*e.index,animated:!1}),ye(),ge.current=setTimeout(()=>{ge.current=null,de.current?.scrollToIndex({index:e.index,animated:!0,viewPosition:0})},50)},[ye]);useEffect(()=>(O||ye(),ye),[O,ye]);return _jsx(Modal,{visible:O,transparent:!0,animationType:"none",onRequestClose:ce,onDismiss:()=>Q.current?.(),statusBarTranslucent:!0,navigationBarTranslucent:!0,children:_jsx(ModalSafeArea,{onInsets:D,children:_jsxs(AnimatedGestureRoot,{collapsable:!1,onLayout:e=>oe(e.nativeEvent.layout.height),style:[StyleSheet.absoluteFill,{backgroundColor:Y}],children:[_jsx(Pressable,{style:StyleSheet.absoluteFill,onPress:ce,accessibilityRole:"button",accessibilityLabel:"Close picker"}),_jsxs(Animated.View,{testID:I,accessibilityViewIsModal:!0,accessibilityLabel:w??s??"Options",style:[P.sheet,{maxHeight:ae,bottom:ie,paddingBottom:ne?16:M.bottom+16,backgroundColor:v.colors.background.elevated,borderTopLeftRadius:v.radius.xl,borderTopRightRadius:v.radius.xl,...smoothCorners,opacity:U,transform:[{translateY:G}],...v.shadows.xl}],children:[_jsx(GestureDetector,{gesture:J,children:_jsxs(View,{children:[_jsx(View,{style:P.sheetHandleRow,children:_jsx(View,{style:[P.sheetHandle,{backgroundColor:v.components.select?.handleColor??v.components.bottomSheet?.handleColor??v.colors.border.primary}]})}),s?_jsx(Text,{style:[P.sheetTitle,{color:v.colors.text.primary,fontSize:v.typography.fontSize.lg,fontWeight:v.typography.fontWeight.semibold,paddingHorizontal:v.spacing.lg,marginBottom:v.spacing.sm}],children:s}):null]})}),j?_jsx(View,{style:[P.searchWrap,{marginHorizontal:v.spacing.lg,marginBottom:v.spacing.sm}],children:_jsxs(View,{style:[P.searchBox,{backgroundColor:v.colors.background.secondary,borderColor:v.colors.border.primary,borderRadius:v.radius.md,...smoothCorners,paddingHorizontal:v.spacing.md,gap:v.spacing.sm}],children:[(v.icons?.search??defaultIcons.search)({size:18,color:v.colors.text.tertiary}),_jsx(TextInput,{value:A,onChangeText:L,placeholder:u,placeholderTextColor:v.colors.text.tertiary,selectionColor:C??v.colors.border.focus,accessibilityLabel:"Search options",style:[P.searchInput,{color:v.colors.text.primary,fontSize:v.typography.fontSize.base,paddingVertical:v.spacing.sm}]}),A.length>0?_jsx(Pressable,{onPress:()=>L(""),hitSlop:8,accessibilityRole:"button",accessibilityLabel:"Clear search",children:(v.icons?.close??defaultIcons.close)({size:18,color:v.colors.text.secondary})}):null]})}):null,_jsxs(View,{style:[P.listWrap,pe?P.listRow:null],children:[_jsx(GestureDetector,{gesture:ee,children:_jsx(FlatList,{ref:de,data:le,keyExtractor:e=>"header"===e.kind?`h:${e.title}`:`o:${e.section??""}:${String(h(e.option))}`,renderItem:({item:e})=>{if("header"===e.kind)return _jsx(View,{accessible:!0,accessibilityRole:"header",style:[P.sectionHeader,{paddingHorizontal:v.spacing.lg,paddingTop:v.spacing.md}],children:l?l(e.title):_jsx(Text,{style:[P.sectionTitle,{color:v.colors.text.tertiary,fontSize:v.typography.fontSize.xs,fontWeight:v.typography.fontWeight.semibold}],children:e.title.toUpperCase()})});const t=e.option,o=m(t),r=h(t),i=f(t),s=b(t),n=x(r),a=g(t),d=y?.(t)??!1;return _jsxs(Pressable,{onPress:()=>S(t),disabled:a,android_ripple:{color:v.colors.surface.pressed,borderless:!1},accessibilityRole:"button",accessibilityLabel:o,accessibilityState:{selected:n,disabled:a},"aria-selected":n,"aria-disabled":a,style:({pressed:e})=>[P.optionRow,{backgroundColor:n?v.colors.surface.selected:e?v.colors.surface.pressed:"transparent",opacity:a?.5:1,paddingHorizontal:v.spacing.lg,paddingVertical:v.spacing.md},R,n?_:null],children:[c?_jsx(View,{style:P.optionTextWrap,children:c(t,{selected:n,disabled:a})}):_jsxs(_Fragment,{children:[s?_jsx(View,{style:P.optionIcon,children:s}):null,_jsxs(View,{style:P.optionTextWrap,children:[_jsx(Text,{style:[P.optionLabel,{color:d?v.colors.toneText.error:n?v.colors.primary:v.colors.text.primary,fontSize:v.typography.fontSize.base,fontWeight:n?v.typography.fontWeight.semibold:v.typography.fontWeight.medium},V,n?k:null],children:o}),i?_jsx(Text,{style:[P.optionDescription,{color:v.colors.text.tertiary,fontSize:v.typography.fontSize.sm}],numberOfLines:2,children:i}):null]})]}),T?_jsx(View,{style:[P.checkbox,{borderColor:n?v.colors.primary:v.colors.border.primary,backgroundColor:n?v.colors.primary:"transparent"}],children:n?_jsx(View,{style:P.checkboxTick}):null}):n?"icon"===v.components.optionSheet?.selectedMarker?_jsx(View,{style:P.singleSelectedIcon,children:(v.icons?.selectedTick??defaultIcons.selectedTick)({size:20,color:v.colors.primary})}):_jsx(View,{style:[P.singleSelectedDot,{backgroundColor:v.colors.primary}]}):null]})},onScrollToIndexFailed:fe,overScrollMode:"never",bounces:!1,keyboardShouldPersistTaps:"handled",showsVerticalScrollIndicator:!pe,style:pe?P.listBesideRail:null,ListEmptyComponent:_jsx(Text,{style:[P.empty,{color:v.colors.text.tertiary,fontSize:v.typography.fontSize.sm,paddingVertical:v.spacing.xl}],children:p})})}),pe?_jsx(View,{style:[P.rail,{paddingRight:v.spacing.xs}],accessibilityRole:"list",accessibilityLabel:"Jump to letter",testID:"option-sheet-alphabet",children:me.map(e=>{const t=ue.has(e);return _jsx(Pressable,{onPress:()=>he(e),disabled:!t,hitSlop:{left:8,right:8},accessibilityRole:"button",accessibilityLabel:`Jump to ${e}`,accessibilityState:{disabled:!t},"aria-disabled":!t,style:P.railLetter,children:_jsx(Text,{style:[P.railLetterText,{color:t?v.colors.primary:v.colors.text.tertiary,fontSize:v.typography.fontSize.xs,fontWeight:v.typography.fontWeight.semibold,opacity:t?1:.45}],children:e})},e)})}):null]}),T?_jsx(View,{style:[P.sheetFooter,{borderTopColor:v.colors.border.secondary,paddingHorizontal:v.spacing.lg,paddingVertical:v.spacing.md}],children:_jsx(Pressable,{onPress:ce,accessibilityRole:"button",accessibilityLabel:"Done",style:({pressed:e})=>[P.doneButton,{backgroundColor:e?v.colors.primaryPressed:v.colors.primary,borderRadius:v.radius.md,...smoothCorners,paddingVertical:v.spacing.sm,paddingHorizontal:v.spacing.lg}],children:_jsx(Text,{style:{color:v.colors.onPrimary,fontSize:v.typography.fontSize.base,fontWeight:v.typography.fontWeight.semibold},children:"Done"})})}):null]}),_jsx(ToastHost,{})]})})})};OptionSheet.displayName="OptionSheet";const transparentOf=e=>{const t=e.match(/^rgba?\(([^)]+)\)$/);if(!t)return"transparent";const[o,r,i]=t[1].split(",").map(e=>e.trim());return`rgba(${o}, ${r}, ${i}, 0)`},buildStyles=e=>StyleSheet.create({sheet:{position:"absolute",left:0,right:0,bottom:0,paddingBottom:16,overflow:"hidden"},sheetHandleRow:{alignItems:"center",paddingTop:10,paddingBottom:8},sheetHandle:{width:36,height:4,borderRadius:2,...smoothCorners},sheetTitle:{includeFontPadding:!1},searchWrap:{width:"auto"},searchBox:{flexDirection:"row",alignItems:"center",borderWidth:1},searchInput:{flex:1,includeFontPadding:!1},optionRow:{flexDirection:"row",alignItems:"center"},sectionHeader:{paddingBottom:4},listWrap:{flexShrink:1},listRow:{flexDirection:"row"},listBesideRail:{flex:1},rail:{justifyContent:"space-between",alignItems:"center",alignSelf:"stretch",paddingVertical:4},railLetter:{paddingHorizontal:4,minHeight:14,justifyContent:"center"},railLetterText:{includeFontPadding:!1,lineHeight:14},sectionTitle:{includeFontPadding:!1,letterSpacing:.6},optionIcon:{marginRight:12},optionTextWrap:{flex:1},optionLabel:{includeFontPadding:!1},optionDescription:{includeFontPadding:!1,marginTop:2},checkbox:{width:22,height:22,borderRadius:6,...smoothCorners,borderWidth:2,alignItems:"center",justifyContent:"center",marginLeft:12},checkboxTick:{width:10,height:6,borderLeftWidth:2,borderBottomWidth:2,borderColor:e.colors.onPrimary,transform:[{rotate:"-45deg"},{translateY:-1}]},singleSelectedDot:{width:8,height:8,borderRadius:4,...smoothCorners,marginLeft:12},singleSelectedIcon:{marginLeft:12},empty:{textAlign:"center"},sheetFooter:{borderTopWidth:StyleSheet.hairlineWidth,alignItems:"flex-end"},doneButton:{alignSelf:"flex-end"}});export default OptionSheet;
@@ -1 +1 @@
1
- "use strict";import{forwardRef,useEffect,useMemo,useRef}from"react";import{Animated,Easing,StyleSheet,Text,View}from"react-native";import{useReducedMotion}from"../../hooks/useReducedMotion.js";import{createAnimatedValue,fontFor,Gradient,setNativeValue,useTheme}from"../../theme/index.js";import{tintOf}from"../../utils/color.js";import{smoothCorners}from"../../utils/corners.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const toneColor=(e,t)=>{switch(t){case"success":return e.colors.success;case"warning":return e.colors.warning;case"error":return e.colors.error;default:return e.colors.primary}},GLOW_LOCATIONS=[0,.35,.5,.65,1],glowOf=e=>{const t=tintOf(e,0,"transparent"),r=tintOf(e,.6,e);return{colors:[t,r,e,r,t],locations:GLOW_LOCATIONS,start:{x:0,y:.5},end:{x:1,y:.5}}},clampProgress=e=>"number"!=typeof e||Number.isNaN(e)||e<0?0:e>1?1:e,ProgressBar=forwardRef((e,t)=>{const r=useTheme(),s=useReducedMotion(),{progress:o,label:i,showPercent:n=!1,indeterminate:a,height:l=6,radius:u,tone:c="primary",trackColor:d,barColor:m,gradient:p,segments:g,animated:f=!0,style:h,containerStyle:y,barStyle:b,accessibilityLabel:w,testID:x}=e,j=a??"number"!=typeof o,R=clampProgress(o),V=useRef(createAnimatedValue(R)).current,S=useRef(createAnimatedValue(0)).current,A=useRef(createAnimatedValue(0)).current,v=useRef(0),_=r.components.progressBar?.determinateAnimationDuration??400,C=r.components.progressBar?.indeterminateLoopDuration??1500,B=r.components.progressBar?.indeterminateWidth??"30%",O=useMemo(()=>buildStyles(r),[r]),N=u??r.radius.full,L=d??r.colors.surface.disabled,M=m??toneColor(r,c),P=useMemo(()=>p?"string"==typeof p?r.gradients[p]??null:p:null,[p,r.gradients]),k=useMemo(()=>glowOf(M),[M]),D=Array.isArray(g)&&g.length>0;useEffect(()=>{j||(f?Animated.timing(V,{toValue:R,duration:_,easing:Easing.bezier(...r.motion.easing.standard),useNativeDriver:!1}).start():V.setValue(R))},[f,R,_,V,j,r]),useEffect(()=>{if(!j||s)return;setNativeValue(S,0);const e=Animated.loop(Animated.timing(S,{toValue:1,duration:C,easing:Easing.inOut(Easing.ease),useNativeDriver:!0}));return e.start(),()=>{e.stop()}},[j,s,S,C]);const E=V.interpolate({inputRange:[0,1],outputRange:["0%","100%"]}),T=S.interpolate({inputRange:[0,1],outputRange:[-1,1]}),G=n&&!j&&!D,F=null!=i||G,I=_jsx(View,{ref:t,accessibilityRole:"progressbar",accessibilityLabel:w??("string"==typeof i?i:void 0),accessibilityValue:j?{text:"Loading"}:{min:0,max:100,now:Math.round(100*R)},testID:x,onLayout:e=>{const t=e.nativeEvent.layout.width;v.current=t,setNativeValue(A,t)},style:[O.track,{height:l,borderRadius:N,...smoothCorners,backgroundColor:L},h,y],children:D?_jsx(View,{style:[O.segments,{height:l}],children:(g??[]).map((e,t)=>_jsx(View,{style:{width:100*clampProgress(e.value)+"%",height:l,backgroundColor:e.color??toneColor(r,e.tone??"primary")}},t))}):_jsx(Animated.View,j?{style:[O.indeterminateBar,{height:l,width:s?"100%":B,transform:s?[]:[{translateX:Animated.multiply(T,A)}]},b],children:_jsx(Gradient,{gradient:k,style:StyleSheet.absoluteFill})}:{style:[O.determinateBar,{height:l,borderRadius:N,...smoothCorners,backgroundColor:P?"transparent":M,width:E,overflow:P?"hidden":void 0},b],children:P?_jsx(Gradient,{gradient:P,style:StyleSheet.absoluteFill}):null})});if(!F)return I;const z={fontSize:r.typography.fontSize.sm,...fontFor(r,"medium")};return _jsxs(View,{style:O.wrapper,children:[_jsxs(View,{style:[O.labelRow,{marginBottom:r.spacing.xs}],children:["string"==typeof i||"number"==typeof i?_jsx(Text,{style:[O.label,z,{color:r.colors.text.primary}],children:i}):_jsx(View,{style:O.label,children:i}),G?_jsx(Text,{accessible:!1,importantForAccessibility:"no",style:[z,{color:r.colors.text.secondary}],children:`${Math.round(100*R)}%`}):null]}),I]})});ProgressBar.displayName="ProgressBar";const buildStyles=e=>StyleSheet.create({wrapper:{width:"100%"},labelRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",columnGap:8},label:{flexShrink:1},track:{width:"100%",overflow:"hidden"},determinateBar:{position:"absolute",left:0,top:0},indeterminateBar:{position:"absolute",left:0,top:0},segments:{flexDirection:"row",width:"100%"}});export{ProgressBar};export default ProgressBar;
1
+ "use strict";import{forwardRef,useEffect,useMemo,useRef}from"react";import{Animated,Easing,StyleSheet,Text,View}from"react-native";import{useReducedMotion}from"../../hooks/useReducedMotion.js";import{createAnimatedValue,fontFor,Gradient,setNativeValue,useTheme}from"../../theme/index.js";import{tintOf}from"../../utils/color.js";import{smoothCorners}from"../../utils/corners.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const toneColor=(e,t)=>{switch(t){case"success":return e.colors.success;case"warning":return e.colors.warning;case"error":return e.colors.error;default:return e.colors.primary}},GLOW_LOCATIONS=[0,.35,.5,.65,1],glowOf=e=>{const t=tintOf(e,0,"transparent"),r=tintOf(e,.6,e);return{colors:[t,r,e,r,t],locations:GLOW_LOCATIONS,start:{x:0,y:.5},end:{x:1,y:.5}}},clampProgress=e=>"number"!=typeof e||Number.isNaN(e)||e<0?0:e>1?1:e,ProgressBar=forwardRef((e,t)=>{const r=useTheme(),o=useReducedMotion(),{progress:s,label:i,showPercent:n=!1,indeterminate:a,height:l=6,radius:u,tone:c="primary",trackColor:d,barColor:m,gradient:p,segments:g,animated:f=!0,style:h,containerStyle:y,barStyle:b,accessibilityLabel:w,testID:x}=e,j=a??"number"!=typeof s,R=clampProgress(s),V=useRef(createAnimatedValue(R)).current,S=useRef(createAnimatedValue(0)).current,A=useRef(createAnimatedValue(0)).current,v=useRef(0),_=r.components.progressBar?.determinateAnimationDuration??400,C=r.components.progressBar?.indeterminateLoopDuration??1500,B=r.components.progressBar?.indeterminateWidth??"30%",O=useMemo(()=>buildStyles(r),[r]),N=u??r.radius.full,L=d??r.colors.surface.disabled,M=m??toneColor(r,c),P=useMemo(()=>p?"string"==typeof p?r.gradients[p]??null:p:null,[p,r.gradients]),k=useMemo(()=>glowOf(M),[M]),D=Array.isArray(g)&&g.length>0;useEffect(()=>{j||(f?Animated.timing(V,{toValue:R,duration:_,easing:Easing.bezier(...r.motion.easing.standard),useNativeDriver:!1}).start():V.setValue(R))},[f,R,_,V,j,r]),useEffect(()=>{if(!j)return;setNativeValue(S,0);const e=Animated.loop(Animated.timing(S,{toValue:1,duration:C,easing:Easing.inOut(Easing.ease),useNativeDriver:!0}));return e.start(),()=>{e.stop()}},[j,S,C]);const E=V.interpolate({inputRange:[0,1],outputRange:["0%","100%"]}),T=S.interpolate({inputRange:[0,1],outputRange:[-1,1]}),G=S.interpolate({inputRange:[0,.5,1],outputRange:[.4,1,.4]}),F=n&&!j&&!D,I=null!=i||F,z=_jsx(View,{ref:t,accessibilityRole:"progressbar",accessibilityLabel:w??("string"==typeof i?i:void 0),accessibilityValue:j?{text:"Loading"}:{min:0,max:100,now:Math.round(100*R)},testID:x,onLayout:e=>{const t=e.nativeEvent.layout.width;v.current=t,setNativeValue(A,t)},style:[O.track,{height:l,borderRadius:N,...smoothCorners,backgroundColor:L},h,y],children:D?_jsx(View,{style:[O.segments,{height:l}],children:(g??[]).map((e,t)=>_jsx(View,{style:{width:100*clampProgress(e.value)+"%",height:l,backgroundColor:e.color??toneColor(r,e.tone??"primary")}},t))}):_jsx(Animated.View,j?{style:[O.indeterminateBar,{height:l,width:o?"100%":B,opacity:o?G:1,transform:o?[]:[{translateX:Animated.multiply(T,A)}]},b],children:_jsx(Gradient,{gradient:k,style:StyleSheet.absoluteFill})}:{style:[O.determinateBar,{height:l,borderRadius:N,...smoothCorners,backgroundColor:P?"transparent":M,width:E,overflow:P?"hidden":void 0},b],children:P?_jsx(Gradient,{gradient:P,style:StyleSheet.absoluteFill}):null})});if(!I)return z;const W={fontSize:r.typography.fontSize.sm,...fontFor(r,"medium")};return _jsxs(View,{style:O.wrapper,children:[_jsxs(View,{style:[O.labelRow,{marginBottom:r.spacing.xs}],children:["string"==typeof i||"number"==typeof i?_jsx(Text,{style:[O.label,W,{color:r.colors.text.primary}],children:i}):_jsx(View,{style:O.label,children:i}),F?_jsx(Text,{accessible:!1,importantForAccessibility:"no",style:[W,{color:r.colors.text.secondary}],children:`${Math.round(100*R)}%`}):null]}),z]})});ProgressBar.displayName="ProgressBar";const buildStyles=e=>StyleSheet.create({wrapper:{width:"100%"},labelRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",columnGap:8},label:{flexShrink:1},track:{width:"100%",overflow:"hidden"},determinateBar:{position:"absolute",left:0,top:0},indeterminateBar:{position:"absolute",left:0,top:0},segments:{flexDirection:"row",width:"100%"}});export{ProgressBar};export default ProgressBar;
@@ -0,0 +1 @@
1
+ "use strict";import{cloneElement,useCallback,useEffect,useMemo,useRef,useState}from"react";import{Animated,BackHandler,FlatList,StyleSheet,View}from"react-native";import{KeyboardStickyView}from"react-native-keyboard-controller";import{useSafeAreaInsets}from"react-native-safe-area-context";import{useRefreshControl}from"../../hooks/useRefreshControl.js";import{useTheme}from"../../theme/index.js";import{AppBar}from"../AppBar/index.js";import{KeyboardAwareScrollView}from"../KeyboardAwareScrollView/index.js";import{KeyboardToolbar}from"../KeyboardToolbar/index.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const DEFAULT_EDGES=["top","bottom"],SCROLL_EVENT_THROTTLE=16,noop=()=>{},buildStyles=e=>StyleSheet.create({flex:{flex:1},root:{flex:1,backgroundColor:e.colors.background.primary},overlay:{position:"absolute",top:0,left:0,right:0},footer:{backgroundColor:e.colors.background.primary,borderTopWidth:StyleSheet.hairlineWidth,borderTopColor:e.colors.border.primary}});export function Screen(e){const{title:t,subtitle:o,largeTitle:r=!0,onBack:n,rightActions:l,leading:i,children:s,onRefresh:a,refreshing:d=!1,footer:c,footerStyle:f,scroll:u=!0,list:p,edges:m=DEFAULT_EDGES,keyboardToolbar:h=!0,contentContainerStyle:y,style:g,testID:b}=e,S=useTheme(),v=useSafeAreaInsets(),x=useMemo(()=>buildStyles(S),[S]),[T]=useState(()=>new Animated.Value(0)),[j,E]=useState(0),k=void 0!==n,A=useRef(n);A.current=n;const C=Boolean(t||o||n||i||l?.length),w=r&&void 0!==t,_=w&&(void 0!==p||u),B=_?j:0,L=void 0!==c,{refreshControl:R}=useRefreshControl({onRefresh:a??noop,refreshing:d}),V=a?cloneElement(R,{progressViewOffset:B}):void 0,K=useMemo(()=>Animated.event([{nativeEvent:{contentOffset:{y:T}}}],{useNativeDriver:!1}),[T]),D=useCallback(e=>{const{height:t}=e.nativeEvent.layout;E(e=>Math.max(e,t))},[]);useEffect(()=>{if(!k)return;const e=BackHandler.addEventListener("hardwareBackPress",()=>(A.current?.(),!0));return()=>e.remove()},[k]);const F=m.includes("left")?v.left:0,I=m.includes("right")?v.right:0,M=m.includes("bottom")?v.bottom:0,O=m.includes("top")&&!C?v.top:0,H=m.filter(e=>"top"!==e&&!("bottom"===e&&L)),G=C?_jsx(View,{style:_?x.overlay:void 0,onLayout:_?D:void 0,children:_jsx(AppBar,{title:t,subtitle:o,variant:w?"large":"default",scrollY:_?T:void 0,onBack:n,rightActions:l,leading:i})}):null;let N;N=void 0!==p?_jsx(FlatList,{keyboardShouldPersistTaps:"handled",...p,refreshControl:V,onScroll:_?K:void 0,scrollEventThrottle:16,style:x.flex,contentContainerStyle:[{paddingTop:B,paddingLeft:F,paddingRight:I},{paddingBottom:L?0:M},p.contentContainerStyle,y]}):u?_jsx(KeyboardAwareScrollView,{refreshControl:V,onScroll:_?K:void 0,safeAreaEdges:H,style:x.flex,contentContainerStyle:[{paddingTop:B},y],children:s}):_jsx(View,{style:[x.flex,{paddingLeft:F,paddingRight:I,paddingBottom:L?0:M},y],children:s});const P=L?_jsx(KeyboardStickyView,{style:[x.footer,{paddingLeft:F,paddingRight:I,paddingBottom:M},f],children:c}):null;return _jsxs(View,{testID:b,style:[x.root,{paddingTop:O},g],children:[_?null:G,N,P,_?G:null,h?_jsx(KeyboardToolbar,{}):null]})}
@@ -0,0 +1 @@
1
+ "use strict";export{Screen}from"./Screen.js";