@lmb-it/kitsconcerto-native 0.1.242 → 0.1.244

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 (286) hide show
  1. package/animations/index.cjs +25 -15
  2. package/animations/index.cjs.map +1 -1
  3. package/animations/index.js +25 -15
  4. package/animations/index.js.map +1 -1
  5. package/apps/mobile/src/Core/AutoComplete/index.cjs +105 -64
  6. package/apps/mobile/src/Core/AutoComplete/index.cjs.map +1 -1
  7. package/apps/mobile/src/Core/AutoComplete/index.js +106 -65
  8. package/apps/mobile/src/Core/AutoComplete/index.js.map +1 -1
  9. package/apps/mobile/src/Core/Dropdown/index.cjs +2 -0
  10. package/apps/mobile/src/Core/Dropdown/index.cjs.map +1 -1
  11. package/apps/mobile/src/Core/Dropdown/index.js +2 -0
  12. package/apps/mobile/src/Core/Dropdown/index.js.map +1 -1
  13. package/apps/mobile/src/Core/Trees/components/CoreToolbar.cjs +2 -0
  14. package/apps/mobile/src/Core/Trees/components/CoreToolbar.cjs.map +1 -1
  15. package/apps/mobile/src/Core/Trees/components/CoreToolbar.js +2 -0
  16. package/apps/mobile/src/Core/Trees/components/CoreToolbar.js.map +1 -1
  17. package/apps/mobile/src/Factory/ResponsiveElement.cjs +2 -0
  18. package/apps/mobile/src/Factory/ResponsiveElement.cjs.map +1 -1
  19. package/apps/mobile/src/Factory/ResponsiveElement.js +2 -0
  20. package/apps/mobile/src/Factory/ResponsiveElement.js.map +1 -1
  21. package/apps/mobile/src/Factory/helpers/cssVarMap.cjs +16 -0
  22. package/apps/mobile/src/Factory/helpers/cssVarMap.cjs.map +1 -1
  23. package/apps/mobile/src/Factory/helpers/cssVarMap.js +16 -0
  24. package/apps/mobile/src/Factory/helpers/cssVarMap.js.map +1 -1
  25. package/apps/mobile/src/Factory/helpers/style.cjs +17 -1
  26. package/apps/mobile/src/Factory/helpers/style.cjs.map +1 -1
  27. package/apps/mobile/src/Factory/helpers/style.js +17 -1
  28. package/apps/mobile/src/Factory/helpers/style.js.map +1 -1
  29. package/apps/mobile/src/Factory/useSeparator.cjs +1 -0
  30. package/apps/mobile/src/Factory/useSeparator.cjs.map +1 -1
  31. package/apps/mobile/src/Factory/useSeparator.js +1 -0
  32. package/apps/mobile/src/Factory/useSeparator.js.map +1 -1
  33. package/components/Accordion/accordion.cjs +2 -0
  34. package/components/Accordion/accordion.cjs.map +1 -1
  35. package/components/Accordion/accordion.js +2 -0
  36. package/components/Accordion/accordion.js.map +1 -1
  37. package/components/Badge/index.cjs +2 -0
  38. package/components/Badge/index.cjs.map +1 -1
  39. package/components/Badge/index.js +2 -0
  40. package/components/Badge/index.js.map +1 -1
  41. package/components/BottomTabBar/index.cjs +2 -0
  42. package/components/BottomTabBar/index.cjs.map +1 -1
  43. package/components/BottomTabBar/index.js +2 -0
  44. package/components/BottomTabBar/index.js.map +1 -1
  45. package/components/Button/Button.cjs +2 -0
  46. package/components/Button/Button.cjs.map +1 -1
  47. package/components/Button/Button.js +2 -0
  48. package/components/Button/Button.js.map +1 -1
  49. package/components/MessageComposer/index.cjs +2 -0
  50. package/components/MessageComposer/index.cjs.map +1 -1
  51. package/components/MessageComposer/index.js +2 -0
  52. package/components/MessageComposer/index.js.map +1 -1
  53. package/components/SegmentedControl/index.cjs +2 -0
  54. package/components/SegmentedControl/index.cjs.map +1 -1
  55. package/components/SegmentedControl/index.js +2 -0
  56. package/components/SegmentedControl/index.js.map +1 -1
  57. package/components/SkeletonText/index.cjs +2 -0
  58. package/components/SkeletonText/index.cjs.map +1 -1
  59. package/components/SkeletonText/index.js +2 -0
  60. package/components/SkeletonText/index.js.map +1 -1
  61. package/components/Tabs/index.cjs +48 -6
  62. package/components/Tabs/index.cjs.map +1 -1
  63. package/components/Tabs/index.js +48 -6
  64. package/components/Tabs/index.js.map +1 -1
  65. package/components/overlay/ConfirmDialog/index.cjs +146 -89
  66. package/components/overlay/ConfirmDialog/index.cjs.map +1 -1
  67. package/components/overlay/ConfirmDialog/index.js +147 -90
  68. package/components/overlay/ConfirmDialog/index.js.map +1 -1
  69. package/components/overlay/Dialog/index.cjs +90 -64
  70. package/components/overlay/Dialog/index.cjs.map +1 -1
  71. package/components/overlay/Dialog/index.js +91 -65
  72. package/components/overlay/Dialog/index.js.map +1 -1
  73. package/components/overlay/Toast/index.cjs +19 -18
  74. package/components/overlay/Toast/index.cjs.map +1 -1
  75. package/components/overlay/Toast/index.js +22 -21
  76. package/components/overlay/Toast/index.js.map +1 -1
  77. package/contexts/Locale/index.cjs +2 -0
  78. package/contexts/Locale/index.cjs.map +1 -1
  79. package/contexts/Locale/index.js +2 -0
  80. package/contexts/Locale/index.js.map +1 -1
  81. package/contexts/Main/index.cjs +2 -0
  82. package/contexts/Main/index.cjs.map +1 -1
  83. package/contexts/Main/index.js +2 -0
  84. package/contexts/Main/index.js.map +1 -1
  85. package/contexts/Theme/KitsThemeProvider.cjs +2 -0
  86. package/contexts/Theme/KitsThemeProvider.cjs.map +1 -1
  87. package/contexts/Theme/KitsThemeProvider.js +2 -0
  88. package/contexts/Theme/KitsThemeProvider.js.map +1 -1
  89. package/contexts/Theme/index.cjs +1 -0
  90. package/contexts/Theme/index.cjs.map +1 -1
  91. package/contexts/Theme/index.js +1 -0
  92. package/contexts/Theme/index.js.map +1 -1
  93. package/contexts/Theme/resolvers.cjs +4 -0
  94. package/contexts/Theme/resolvers.cjs.map +1 -1
  95. package/contexts/Theme/resolvers.js +4 -0
  96. package/contexts/Theme/resolvers.js.map +1 -1
  97. package/data/DataView/Pagination/index.cjs +2 -0
  98. package/data/DataView/Pagination/index.cjs.map +1 -1
  99. package/data/DataView/Pagination/index.js +2 -0
  100. package/data/DataView/Pagination/index.js.map +1 -1
  101. package/data/TreeView/index.cjs +2 -0
  102. package/data/TreeView/index.cjs.map +1 -1
  103. package/data/TreeView/index.js +2 -0
  104. package/data/TreeView/index.js.map +1 -1
  105. package/form/controls/Checkbox/checkbox.cjs +2 -0
  106. package/form/controls/Checkbox/checkbox.cjs.map +1 -1
  107. package/form/controls/Checkbox/checkbox.js +2 -0
  108. package/form/controls/Checkbox/checkbox.js.map +1 -1
  109. package/form/controls/RadioButton/radiobutton.cjs +2 -0
  110. package/form/controls/RadioButton/radiobutton.cjs.map +1 -1
  111. package/form/controls/RadioButton/radiobutton.js +2 -0
  112. package/form/controls/RadioButton/radiobutton.js.map +1 -1
  113. package/form/controls/SelectButton/index.cjs +2 -0
  114. package/form/controls/SelectButton/index.cjs.map +1 -1
  115. package/form/controls/SelectButton/index.js +2 -0
  116. package/form/controls/SelectButton/index.js.map +1 -1
  117. package/form/controls/TriStateCheckbox/index.cjs +2 -0
  118. package/form/controls/TriStateCheckbox/index.cjs.map +1 -1
  119. package/form/controls/TriStateCheckbox/index.js +2 -0
  120. package/form/controls/TriStateCheckbox/index.js.map +1 -1
  121. package/form/file-pickers/MainUploader/index.cjs +1 -0
  122. package/form/file-pickers/MainUploader/index.cjs.map +1 -1
  123. package/form/file-pickers/MainUploader/index.js +1 -0
  124. package/form/file-pickers/MainUploader/index.js.map +1 -1
  125. package/form/helpers/ErrorMessage/errormessage.cjs +2 -0
  126. package/form/helpers/ErrorMessage/errormessage.cjs.map +1 -1
  127. package/form/helpers/ErrorMessage/errormessage.js +2 -0
  128. package/form/helpers/ErrorMessage/errormessage.js.map +1 -1
  129. package/form/helpers/FormContainer/index.cjs +2 -0
  130. package/form/helpers/FormContainer/index.cjs.map +1 -1
  131. package/form/helpers/FormContainer/index.js +2 -0
  132. package/form/helpers/FormContainer/index.js.map +1 -1
  133. package/form/helpers/Label/label.cjs +2 -0
  134. package/form/helpers/Label/label.cjs.map +1 -1
  135. package/form/helpers/Label/label.js +2 -0
  136. package/form/helpers/Label/label.js.map +1 -1
  137. package/form/inputs/InputMask/index.cjs +2 -0
  138. package/form/inputs/InputMask/index.cjs.map +1 -1
  139. package/form/inputs/InputMask/index.js +2 -0
  140. package/form/inputs/InputMask/index.js.map +1 -1
  141. package/form/inputs/InputNumber/index.cjs +2 -0
  142. package/form/inputs/InputNumber/index.cjs.map +1 -1
  143. package/form/inputs/InputNumber/index.js +2 -0
  144. package/form/inputs/InputNumber/index.js.map +1 -1
  145. package/form/inputs/InputPassword/index.cjs +2 -0
  146. package/form/inputs/InputPassword/index.cjs.map +1 -1
  147. package/form/inputs/InputPassword/index.js +2 -0
  148. package/form/inputs/InputPassword/index.js.map +1 -1
  149. package/form/inputs/InputSwitch/index.cjs +2 -0
  150. package/form/inputs/InputSwitch/index.cjs.map +1 -1
  151. package/form/inputs/InputSwitch/index.js +2 -0
  152. package/form/inputs/InputSwitch/index.js.map +1 -1
  153. package/form/inputs/InputText/index.cjs +2 -0
  154. package/form/inputs/InputText/index.cjs.map +1 -1
  155. package/form/inputs/InputText/index.js +2 -0
  156. package/form/inputs/InputText/index.js.map +1 -1
  157. package/form/inputs/InputTextarea/index.cjs +2 -0
  158. package/form/inputs/InputTextarea/index.cjs.map +1 -1
  159. package/form/inputs/InputTextarea/index.js +2 -0
  160. package/form/inputs/InputTextarea/index.js.map +1 -1
  161. package/form/inputs/PhoneInput/index.cjs +2 -0
  162. package/form/inputs/PhoneInput/index.cjs.map +1 -1
  163. package/form/inputs/PhoneInput/index.js +2 -0
  164. package/form/inputs/PhoneInput/index.js.map +1 -1
  165. package/form/inputs/RadiusPicker/components/NumericRadiusInput.cjs +1 -0
  166. package/form/inputs/RadiusPicker/components/NumericRadiusInput.cjs.map +1 -1
  167. package/form/inputs/RadiusPicker/components/NumericRadiusInput.js +1 -0
  168. package/form/inputs/RadiusPicker/components/NumericRadiusInput.js.map +1 -1
  169. package/form/selects/AutoComplete/index.cjs +2 -0
  170. package/form/selects/AutoComplete/index.cjs.map +1 -1
  171. package/form/selects/AutoComplete/index.js +2 -0
  172. package/form/selects/AutoComplete/index.js.map +1 -1
  173. package/form/selects/Dropdown/index.cjs +2 -0
  174. package/form/selects/Dropdown/index.cjs.map +1 -1
  175. package/form/selects/Dropdown/index.js +2 -0
  176. package/form/selects/Dropdown/index.js.map +1 -1
  177. package/form/selects/ListBox/index.cjs +2 -0
  178. package/form/selects/ListBox/index.cjs.map +1 -1
  179. package/form/selects/ListBox/index.js +2 -0
  180. package/form/selects/ListBox/index.js.map +1 -1
  181. package/form/selects/MultiSelect/index.cjs +2 -0
  182. package/form/selects/MultiSelect/index.cjs.map +1 -1
  183. package/form/selects/MultiSelect/index.js +2 -0
  184. package/form/selects/MultiSelect/index.js.map +1 -1
  185. package/form/selects/TreeSelect/index.cjs +2 -0
  186. package/form/selects/TreeSelect/index.cjs.map +1 -1
  187. package/form/selects/TreeSelect/index.js +2 -0
  188. package/form/selects/TreeSelect/index.js.map +1 -1
  189. package/form-renderer/components/layout/FieldWrapper.cjs +2 -0
  190. package/form-renderer/components/layout/FieldWrapper.cjs.map +1 -1
  191. package/form-renderer/components/layout/FieldWrapper.js +2 -0
  192. package/form-renderer/components/layout/FieldWrapper.js.map +1 -1
  193. package/hooks/shadowPresets.cjs +1 -0
  194. package/hooks/shadowPresets.cjs.map +1 -1
  195. package/hooks/shadowPresets.js +1 -0
  196. package/hooks/shadowPresets.js.map +1 -1
  197. package/hooks/useFocusStyles.cjs +2 -0
  198. package/hooks/useFocusStyles.cjs.map +1 -1
  199. package/hooks/useFocusStyles.js +2 -0
  200. package/hooks/useFocusStyles.js.map +1 -1
  201. package/index.cjs +5 -0
  202. package/index.cjs.map +1 -1
  203. package/index.d.ts +51 -1
  204. package/index.js +1 -0
  205. package/index.js.map +1 -1
  206. package/layout/Center/index.cjs +2 -0
  207. package/layout/Center/index.cjs.map +1 -1
  208. package/layout/Center/index.js +2 -0
  209. package/layout/Center/index.js.map +1 -1
  210. package/layout/Container/container.cjs +2 -0
  211. package/layout/Container/container.cjs.map +1 -1
  212. package/layout/Container/container.js +2 -0
  213. package/layout/Container/container.js.map +1 -1
  214. package/layout/Flex/index.cjs +2 -0
  215. package/layout/Flex/index.cjs.map +1 -1
  216. package/layout/Flex/index.js +2 -0
  217. package/layout/Flex/index.js.map +1 -1
  218. package/layout/HStack/index.cjs +2 -0
  219. package/layout/HStack/index.cjs.map +1 -1
  220. package/layout/HStack/index.js +2 -0
  221. package/layout/HStack/index.js.map +1 -1
  222. package/layout/List/index.cjs +2 -0
  223. package/layout/List/index.cjs.map +1 -1
  224. package/layout/List/index.js +2 -0
  225. package/layout/List/index.js.map +1 -1
  226. package/layout/ListItem/index.cjs +2 -0
  227. package/layout/ListItem/index.cjs.map +1 -1
  228. package/layout/ListItem/index.js +2 -0
  229. package/layout/ListItem/index.js.map +1 -1
  230. package/layout/ScrollView/index.cjs +2 -0
  231. package/layout/ScrollView/index.cjs.map +1 -1
  232. package/layout/ScrollView/index.js +2 -0
  233. package/layout/ScrollView/index.js.map +1 -1
  234. package/layout/VStack/index.cjs +2 -0
  235. package/layout/VStack/index.cjs.map +1 -1
  236. package/layout/VStack/index.js +2 -0
  237. package/layout/VStack/index.js.map +1 -1
  238. package/package.json +1 -1
  239. package/packages/types/src/Theme/alphaColors.cjs +24 -0
  240. package/packages/types/src/Theme/alphaColors.cjs.map +1 -0
  241. package/packages/types/src/Theme/alphaColors.js +19 -0
  242. package/packages/types/src/Theme/alphaColors.js.map +1 -0
  243. package/packages/types/src/Theme/defaultTheme.cjs +1 -1
  244. package/packages/types/src/Theme/defaultTheme.cjs.map +1 -1
  245. package/packages/types/src/Theme/defaultTheme.js +1 -1
  246. package/packages/types/src/Theme/defaultTheme.js.map +1 -1
  247. package/packages/types/src/Theme/resolvers.cjs +6 -0
  248. package/packages/types/src/Theme/resolvers.cjs.map +1 -1
  249. package/packages/types/src/Theme/resolvers.js +6 -0
  250. package/packages/types/src/Theme/resolvers.js.map +1 -1
  251. package/primitives/Box/index.cjs +2 -0
  252. package/primitives/Box/index.cjs.map +1 -1
  253. package/primitives/Box/index.js +2 -0
  254. package/primitives/Box/index.js.map +1 -1
  255. package/primitives/Card/index.cjs +2 -0
  256. package/primitives/Card/index.cjs.map +1 -1
  257. package/primitives/Card/index.js +2 -0
  258. package/primitives/Card/index.js.map +1 -1
  259. package/primitives/Divider/index.cjs +2 -0
  260. package/primitives/Divider/index.cjs.map +1 -1
  261. package/primitives/Divider/index.js +2 -0
  262. package/primitives/Divider/index.js.map +1 -1
  263. package/primitives/Heading/index.cjs +2 -0
  264. package/primitives/Heading/index.cjs.map +1 -1
  265. package/primitives/Heading/index.js +2 -0
  266. package/primitives/Heading/index.js.map +1 -1
  267. package/primitives/Icon/index.cjs +1 -0
  268. package/primitives/Icon/index.cjs.map +1 -1
  269. package/primitives/Icon/index.js +1 -0
  270. package/primitives/Icon/index.js.map +1 -1
  271. package/primitives/Image/index.cjs +2 -0
  272. package/primitives/Image/index.cjs.map +1 -1
  273. package/primitives/Image/index.js +2 -0
  274. package/primitives/Image/index.js.map +1 -1
  275. package/primitives/Skeleton/index.cjs +2 -0
  276. package/primitives/Skeleton/index.cjs.map +1 -1
  277. package/primitives/Skeleton/index.js +2 -0
  278. package/primitives/Skeleton/index.js.map +1 -1
  279. package/primitives/Svg/index.cjs +2 -0
  280. package/primitives/Svg/index.cjs.map +1 -1
  281. package/primitives/Svg/index.js +2 -0
  282. package/primitives/Svg/index.js.map +1 -1
  283. package/primitives/Text/index.cjs +2 -0
  284. package/primitives/Text/index.cjs.map +1 -1
  285. package/primitives/Text/index.js +2 -0
  286. package/primitives/Text/index.js.map +1 -1
@@ -3,36 +3,46 @@
3
3
  const overlayAnimations = {
4
4
  // ── Backdrop / scrim ─────────────────────────────────────
5
5
  scrim: {
6
- enterDuration: 200},
6
+ enterDuration: 120,
7
+ exitDuration: 100
8
+ },
7
9
  // ── Centered Dialog panel ────────────────────────────────
10
+ // Enter: critically-ish damped spring — snappy but settles cleanly (no
11
+ // ringing). Exit: timing-based zoom-out (springs are enter-only).
8
12
  dialog: {
9
- enter: { damping: 0, stiffness: 600 }
13
+ enter: { damping: 26, stiffness: 420, mass: 1 },
14
+ exitDuration: 120
10
15
  },
11
16
  // ── Confirm dialog ───────────────────────────────────────
12
17
  confirm: {
13
18
  /** Centered confirm panel pop. */
14
- enter: { damping: 0, stiffness: 600 },
19
+ enter: { damping: 26, stiffness: 420, mass: 1 },
15
20
  /** Floating severity-icon bubble — pops in slightly after the panel. */
16
- icon: { damping: 0, stiffness: 600, delay: 100 },
21
+ icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },
17
22
  /** Content-only / prompt panel (no header/buttons chrome). */
18
- content: { damping: 0, stiffness: 600 }
23
+ content: { damping: 26, stiffness: 420, mass: 1 },
24
+ /** Timed zoom-out for the confirm center/content panels. */
25
+ exitDuration: 120
19
26
  },
20
27
  // ── Bottom sheet (Dialog + Confirm, position="bottom") ───
28
+ // Slightly heavier damping/lower stiffness so the sheet glides up without
29
+ // overshoot. Exit: timed slide-down.
21
30
  sheet: {
22
- enter: { damping: 0, stiffness: 600 }
31
+ enter: { damping: 30, stiffness: 400, mass: 1 },
32
+ exitDuration: 150
23
33
  },
24
34
  // ── Toast ────────────────────────────────────────────────
35
+ // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND
36
+ // translateY together, so there is no second concurrent layer to desync.
25
37
  toast: {
26
- /** Toast slides up/down into view. */
27
- slideInDuration: 100,
28
- /** Toast slides back out. */
29
- slideOutDuration: 200,
38
+ /** Merged fade+slide entrance (position-appropriate direction). */
39
+ enter: { damping: 30, stiffness: 400, mass: 1 },
40
+ /** Timed fade+slide out. */
41
+ exitDuration: 120,
30
42
  /** Re-positioning when toasts stack/unstack. */
31
- layoutDuration: 200,
32
- /** Inner toast card cross-fade in. */
33
- itemEnterDuration: 200,
34
- /** Inner toast card cross-fade out. */
35
- itemExitDuration: 150
43
+ layoutDuration: 150,
44
+ /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */
45
+ keyboardGap: 8
36
46
  }
37
47
  };
38
48
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /** Dimmed backdrop behind every overlay (fade). */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring). */\n dialog: { enter: ISpringConfig };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig };\n /** Bottom sheet shared by Dialog & Confirm (slide-up spring). */\n sheet: { enter: ISpringConfig };\n /** Toast — slide in/out, item cross-fade, and position re-layout. */\n toast: {\n slideInDuration: number;\n slideOutDuration: number;\n layoutDuration: number;\n itemEnterDuration: number;\n itemExitDuration: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 200,\n exitDuration: 150,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n dialog: {\n enter: { damping: 0, stiffness: 600 },\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 0, stiffness: 600 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 0, stiffness: 600, delay: 100 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 0, stiffness: 600 },\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n sheet: {\n enter: { damping: 0, stiffness: 600 },\n },\n\n // ── Toast ────────────────────────────────────────────────\n toast: {\n /** Toast slides up/down into view. */\n slideInDuration: 100,\n /** Toast slides back out. */\n slideOutDuration: 200,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 200,\n /** Inner toast card cross-fade in. */\n itemEnterDuration: 200,\n /** Inner toast card cross-fade out. */\n itemExitDuration: 150,\n },\n};\n\nexport default overlayAnimations;\n"],"names":[],"mappings":";;AAiDO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAEnB,CAAA;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACJ,KAAA,EAAO,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA;AAAI,GACxC;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,KAAA,EAAO,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA,EAAI;AAAA;AAAA,IAEpC,MAAM,EAAE,OAAA,EAAS,GAAG,SAAA,EAAW,GAAA,EAAK,OAAO,GAAA,EAAI;AAAA;AAAA,IAE/C,OAAA,EAAS,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA;AAAI,GAC1C;AAAA;AAAA,EAGA,KAAA,EAAO;AAAA,IACH,KAAA,EAAO,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA;AAAI,GACxC;AAAA;AAAA,EAGA,KAAA,EAAO;AAAA;AAAA,IAEH,eAAA,EAAiB,GAAA;AAAA;AAAA,IAEjB,gBAAA,EAAkB,GAAA;AAAA;AAAA,IAElB,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,iBAAA,EAAmB,GAAA;AAAA;AAAA,IAEnB,gBAAA,EAAkB;AAAA;AAE1B;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.mass()` — heavier = slower / more inertia. Defaults to 1. */\n mass?: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /** Dimmed backdrop behind every overlay (fade in/out). */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring in, timed zoom-out). */\n dialog: { enter: ISpringConfig; exitDuration: number };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig; exitDuration: number };\n /** Bottom sheet shared by Dialog & Confirm (slide-up spring in, timed slide-down out). */\n sheet: { enter: ISpringConfig; exitDuration: number };\n /** Toast — single merged fade+slide entrance, timed exit, re-layout, keyboard gap. */\n toast: {\n enter: ISpringConfig;\n exitDuration: number;\n layoutDuration: number;\n keyboardGap: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 120,\n exitDuration: 100,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n // Enter: critically-ish damped spring — snappy but settles cleanly (no\n // ringing). Exit: timing-based zoom-out (springs are enter-only).\n dialog: {\n enter: { damping: 26, stiffness: 420, mass: 1 },\n exitDuration: 120,\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 26, stiffness: 420, mass: 1 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 26, stiffness: 420, mass: 1 },\n /** Timed zoom-out for the confirm center/content panels. */\n exitDuration: 120,\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n // Slightly heavier damping/lower stiffness so the sheet glides up without\n // overshoot. Exit: timed slide-down.\n sheet: {\n enter: { damping: 30, stiffness: 400, mass: 1 },\n exitDuration: 150,\n },\n\n // ── Toast ────────────────────────────────────────────────\n // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND\n // translateY together, so there is no second concurrent layer to desync.\n toast: {\n /** Merged fade+slide entrance (position-appropriate direction). */\n enter: { damping: 30, stiffness: 400, mass: 1 },\n /** Timed fade+slide out. */\n exitDuration: 120,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 150,\n /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */\n keyboardGap: 8,\n },\n};\n\nexport default overlayAnimations;\n"],"names":[],"mappings":";;AAkDO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAAA;AAAA,IACf,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,EAAQ;AAAA,IACJ,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,IAAA,EAAM,EAAE,OAAA,EAAS,EAAA,EAAI,WAAW,GAAA,EAAK,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,EAAA,EAAG;AAAA;AAAA,IAExD,SAAS,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAEhD,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA,IACH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA;AAAA,IAEH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,YAAA,EAAc,GAAA;AAAA;AAAA,IAEd,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,WAAA,EAAa;AAAA;AAErB;;;;"}
@@ -1,36 +1,46 @@
1
1
  const overlayAnimations = {
2
2
  // ── Backdrop / scrim ─────────────────────────────────────
3
3
  scrim: {
4
- enterDuration: 200},
4
+ enterDuration: 120,
5
+ exitDuration: 100
6
+ },
5
7
  // ── Centered Dialog panel ────────────────────────────────
8
+ // Enter: critically-ish damped spring — snappy but settles cleanly (no
9
+ // ringing). Exit: timing-based zoom-out (springs are enter-only).
6
10
  dialog: {
7
- enter: { damping: 0, stiffness: 600 }
11
+ enter: { damping: 26, stiffness: 420, mass: 1 },
12
+ exitDuration: 120
8
13
  },
9
14
  // ── Confirm dialog ───────────────────────────────────────
10
15
  confirm: {
11
16
  /** Centered confirm panel pop. */
12
- enter: { damping: 0, stiffness: 600 },
17
+ enter: { damping: 26, stiffness: 420, mass: 1 },
13
18
  /** Floating severity-icon bubble — pops in slightly after the panel. */
14
- icon: { damping: 0, stiffness: 600, delay: 100 },
19
+ icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },
15
20
  /** Content-only / prompt panel (no header/buttons chrome). */
16
- content: { damping: 0, stiffness: 600 }
21
+ content: { damping: 26, stiffness: 420, mass: 1 },
22
+ /** Timed zoom-out for the confirm center/content panels. */
23
+ exitDuration: 120
17
24
  },
18
25
  // ── Bottom sheet (Dialog + Confirm, position="bottom") ───
26
+ // Slightly heavier damping/lower stiffness so the sheet glides up without
27
+ // overshoot. Exit: timed slide-down.
19
28
  sheet: {
20
- enter: { damping: 0, stiffness: 600 }
29
+ enter: { damping: 30, stiffness: 400, mass: 1 },
30
+ exitDuration: 150
21
31
  },
22
32
  // ── Toast ────────────────────────────────────────────────
33
+ // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND
34
+ // translateY together, so there is no second concurrent layer to desync.
23
35
  toast: {
24
- /** Toast slides up/down into view. */
25
- slideInDuration: 100,
26
- /** Toast slides back out. */
27
- slideOutDuration: 200,
36
+ /** Merged fade+slide entrance (position-appropriate direction). */
37
+ enter: { damping: 30, stiffness: 400, mass: 1 },
38
+ /** Timed fade+slide out. */
39
+ exitDuration: 120,
28
40
  /** Re-positioning when toasts stack/unstack. */
29
- layoutDuration: 200,
30
- /** Inner toast card cross-fade in. */
31
- itemEnterDuration: 200,
32
- /** Inner toast card cross-fade out. */
33
- itemExitDuration: 150
41
+ layoutDuration: 150,
42
+ /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */
43
+ keyboardGap: 8
34
44
  }
35
45
  };
36
46
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /** Dimmed backdrop behind every overlay (fade). */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring). */\n dialog: { enter: ISpringConfig };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig };\n /** Bottom sheet shared by Dialog & Confirm (slide-up spring). */\n sheet: { enter: ISpringConfig };\n /** Toast — slide in/out, item cross-fade, and position re-layout. */\n toast: {\n slideInDuration: number;\n slideOutDuration: number;\n layoutDuration: number;\n itemEnterDuration: number;\n itemExitDuration: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 200,\n exitDuration: 150,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n dialog: {\n enter: { damping: 0, stiffness: 600 },\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 0, stiffness: 600 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 0, stiffness: 600, delay: 100 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 0, stiffness: 600 },\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n sheet: {\n enter: { damping: 0, stiffness: 600 },\n },\n\n // ── Toast ────────────────────────────────────────────────\n toast: {\n /** Toast slides up/down into view. */\n slideInDuration: 100,\n /** Toast slides back out. */\n slideOutDuration: 200,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 200,\n /** Inner toast card cross-fade in. */\n itemEnterDuration: 200,\n /** Inner toast card cross-fade out. */\n itemExitDuration: 150,\n },\n};\n\nexport default overlayAnimations;\n"],"names":[],"mappings":"AAiDO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAEnB,CAAA;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACJ,KAAA,EAAO,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA;AAAI,GACxC;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,KAAA,EAAO,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA,EAAI;AAAA;AAAA,IAEpC,MAAM,EAAE,OAAA,EAAS,GAAG,SAAA,EAAW,GAAA,EAAK,OAAO,GAAA,EAAI;AAAA;AAAA,IAE/C,OAAA,EAAS,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA;AAAI,GAC1C;AAAA;AAAA,EAGA,KAAA,EAAO;AAAA,IACH,KAAA,EAAO,EAAE,OAAA,EAAS,CAAA,EAAG,WAAW,GAAA;AAAI,GACxC;AAAA;AAAA,EAGA,KAAA,EAAO;AAAA;AAAA,IAEH,eAAA,EAAiB,GAAA;AAAA;AAAA,IAEjB,gBAAA,EAAkB,GAAA;AAAA;AAAA,IAElB,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,iBAAA,EAAmB,GAAA;AAAA;AAAA,IAEnB,gBAAA,EAAkB;AAAA;AAE1B;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/animations/index.ts"],"sourcesContent":["/**\n * ════════════════════════════════════════════════════════════════════════\n * Overlay animation tuning — EDIT THIS FILE TO CONTROL ALL OVERLAY MOTION\n * ════════════════════════════════════════════════════════════════════════\n *\n * Every in/out animation value used by the animated overlay components on\n * React Native (reanimated) lives here. Change a number and it updates\n * everywhere that animation is used — no need to touch the component files.\n *\n * Consumed by (native):\n * • components/overlay/Dialog/index.native.tsx\n * • components/overlay/ConfirmDialog/index.native.tsx\n * • components/overlay/Toast/index.native.tsx\n *\n * Two kinds of value:\n * • spring → reanimated `.springify().damping(d).stiffness(s)` (+ optional `.delay`)\n * - damping ↓ lower = bouncier, longer settle\n * - stiffness ↑ higher = snappier, faster\n * • duration → milliseconds for `.duration(ms)` (timing-based fade/slide)\n */\n\nexport interface ISpringConfig {\n /** reanimated `.damping()` — lower = bouncier / slower to settle. */\n damping: number;\n /** reanimated `.stiffness()` — higher = snappier / faster. */\n stiffness: number;\n /** reanimated `.mass()` — heavier = slower / more inertia. Defaults to 1. */\n mass?: number;\n /** reanimated `.delay()` in ms — wait before the animation starts. */\n delay?: number;\n}\n\nexport interface IOverlayAnimations {\n /** Dimmed backdrop behind every overlay (fade in/out). */\n scrim: { enterDuration: number; exitDuration: number };\n /** Centered Dialog panel (zoom-in spring in, timed zoom-out). */\n dialog: { enter: ISpringConfig; exitDuration: number };\n /** Confirm: centered panel, its floating icon bubble, and the content-only/prompt panel. */\n confirm: { enter: ISpringConfig; icon: ISpringConfig; content: ISpringConfig; exitDuration: number };\n /** Bottom sheet shared by Dialog & Confirm (slide-up spring in, timed slide-down out). */\n sheet: { enter: ISpringConfig; exitDuration: number };\n /** Toast — single merged fade+slide entrance, timed exit, re-layout, keyboard gap. */\n toast: {\n enter: ISpringConfig;\n exitDuration: number;\n layoutDuration: number;\n keyboardGap: number;\n };\n}\n\nexport const overlayAnimations: IOverlayAnimations = {\n // ── Backdrop / scrim ─────────────────────────────────────\n scrim: {\n enterDuration: 120,\n exitDuration: 100,\n },\n\n // ── Centered Dialog panel ────────────────────────────────\n // Enter: critically-ish damped spring — snappy but settles cleanly (no\n // ringing). Exit: timing-based zoom-out (springs are enter-only).\n dialog: {\n enter: { damping: 26, stiffness: 420, mass: 1 },\n exitDuration: 120,\n },\n\n // ── Confirm dialog ───────────────────────────────────────\n confirm: {\n /** Centered confirm panel pop. */\n enter: { damping: 26, stiffness: 420, mass: 1 },\n /** Floating severity-icon bubble — pops in slightly after the panel. */\n icon: { damping: 26, stiffness: 420, mass: 1, delay: 60 },\n /** Content-only / prompt panel (no header/buttons chrome). */\n content: { damping: 26, stiffness: 420, mass: 1 },\n /** Timed zoom-out for the confirm center/content panels. */\n exitDuration: 120,\n },\n\n // ── Bottom sheet (Dialog + Confirm, position=\"bottom\") ───\n // Slightly heavier damping/lower stiffness so the sheet glides up without\n // overshoot. Exit: timed slide-down.\n sheet: {\n enter: { damping: 30, stiffness: 400, mass: 1 },\n exitDuration: 150,\n },\n\n // ── Toast ────────────────────────────────────────────────\n // One element owns the entrance: FadeInUp/FadeInDown animate opacity AND\n // translateY together, so there is no second concurrent layer to desync.\n toast: {\n /** Merged fade+slide entrance (position-appropriate direction). */\n enter: { damping: 30, stiffness: 400, mass: 1 },\n /** Timed fade+slide out. */\n exitDuration: 120,\n /** Re-positioning when toasts stack/unstack. */\n layoutDuration: 150,\n /** Gap (pt) kept between a bottom toast and the keyboard when it opens. */\n keyboardGap: 8,\n },\n};\n\nexport default overlayAnimations;\n"],"names":[],"mappings":"AAkDO,MAAM,iBAAA,GAAwC;AAAA;AAAA,EAEjD,KAAA,EAAO;AAAA,IACH,aAAA,EAAe,GAAA;AAAA,IACf,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,EAAQ;AAAA,IACJ,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA;AAAA,IAEL,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,IAAA,EAAM,EAAE,OAAA,EAAS,EAAA,EAAI,WAAW,GAAA,EAAK,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,EAAA,EAAG;AAAA;AAAA,IAExD,SAAS,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAEhD,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA,IACH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA,IAC9C,YAAA,EAAc;AAAA,GAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,EAAO;AAAA;AAAA,IAEH,OAAO,EAAE,OAAA,EAAS,IAAI,SAAA,EAAW,GAAA,EAAK,MAAM,CAAA,EAAE;AAAA;AAAA,IAE9C,YAAA,EAAc,GAAA;AAAA;AAAA,IAEd,cAAA,EAAgB,GAAA;AAAA;AAAA,IAEhB,WAAA,EAAa;AAAA;AAErB;;;;"}
@@ -15,6 +15,7 @@ const resolveLabel = (item, field) => {
15
15
  return String(item[field] ?? "");
16
16
  };
17
17
  const t = style.resolveThemeTokenForNative;
18
+ const INPUT_CHROME_RADIUS = 10;
18
19
  const TEXT_STYLE_KEYS = /* @__PURE__ */ new Set([
19
20
  "fontSize",
20
21
  "fontFamily",
@@ -92,6 +93,13 @@ function AutoComplete({
92
93
  const [focused, setFocused] = React.useState(false);
93
94
  const [highlightedIndex, setHighlightedIndex] = React.useState(-1);
94
95
  const [triggerLayout, setTriggerLayout] = React.useState(null);
96
+ const overlayAnchorRef = React.useRef(null);
97
+ const [overlayOrigin, setOverlayOrigin] = React.useState({ x: 0, y: 0 });
98
+ const measureOverlayOrigin = React.useCallback(() => {
99
+ overlayAnchorRef.current?.measureInWindow((x, y) => {
100
+ setOverlayOrigin((prev) => prev.x === x && prev.y === y ? prev : { x, y });
101
+ });
102
+ }, []);
95
103
  const [keyboardHeight, setKeyboardHeight] = React.useState(0);
96
104
  const onChangeRef = React.useRef(onChange);
97
105
  onChangeRef.current = onChange;
@@ -170,9 +178,10 @@ function AutoComplete({
170
178
  triggerRef.current?.measureInWindow((x, y, width, height) => {
171
179
  setTriggerLayout({ x, y, width, height });
172
180
  });
181
+ measureOverlayOrigin();
173
182
  }, 100);
174
183
  return () => clearTimeout(timer);
175
- }, [keyboardHeight, selectedValues.length]);
184
+ }, [keyboardHeight, selectedValues.length, measureOverlayOrigin]);
176
185
  React.useEffect(() => {
177
186
  if (autoHighlight && flatData.length > 0 && panelVisible) {
178
187
  const firstNonGroup = flatData.findIndex((d) => !d.__group);
@@ -190,7 +199,8 @@ function AutoComplete({
190
199
  triggerRef.current?.measureInWindow((x, y, width, height) => {
191
200
  setTriggerLayout({ x, y, width, height });
192
201
  });
193
- }, []);
202
+ measureOverlayOrigin();
203
+ }, [measureOverlayOrigin]);
194
204
  const hidePanel = React.useCallback(() => {
195
205
  if (__DEV__) console.log("[AC] hidePanel()");
196
206
  setPanelVisible((prev) => {
@@ -361,7 +371,15 @@ function AutoComplete({
361
371
  );
362
372
  const borderColor = invalid ? colors.borderInvalid : focused ? colors.borderFocus : colors.border;
363
373
  const showPanelContent = panelVisible && (flatData.length > 0 || showEmptyMessage || !!emptyMessage);
364
- const resolvedBorderRadius = wrapperOverrides?.borderRadius ?? styles.inputWrapper.borderRadius;
374
+ const panelRadius = React.useMemo(() => {
375
+ const explicit = panelStyle?.borderRadius;
376
+ if (typeof explicit === "number") return explicit;
377
+ const wrapperRadius = wrapperOverrides?.borderRadius;
378
+ if (typeof wrapperRadius === "number" && wrapperRadius > 0) {
379
+ return Math.min(wrapperRadius, 16);
380
+ }
381
+ return INPUT_CHROME_RADIUS;
382
+ }, [panelStyle, wrapperOverrides]);
365
383
  const panelGeometry = React.useMemo(() => {
366
384
  if (!showPanelContent || !triggerLayout) return null;
367
385
  const screen = reactNative.Dimensions.get("window");
@@ -382,6 +400,8 @@ function AutoComplete({
382
400
  maxH
383
401
  };
384
402
  }, [showPanelContent, triggerLayout, scrollHeight, keyboardHeight]);
403
+ const panelTop = panelGeometry ? panelGeometry.top - overlayOrigin.y : 0;
404
+ const panelLeft = panelGeometry ? panelGeometry.left - overlayOrigin.x : 0;
385
405
  if (__DEV__)
386
406
  console.log("[AC] render", {
387
407
  panelVisible,
@@ -405,6 +425,7 @@ function AutoComplete({
405
425
  triggerRef.current?.measureInWindow((x, y, width, height) => {
406
426
  setTriggerLayout({ x, y, width, height });
407
427
  });
428
+ measureOverlayOrigin();
408
429
  },
409
430
  style: [
410
431
  styles.inputWrapper,
@@ -465,74 +486,86 @@ function AutoComplete({
465
486
  ]
466
487
  }
467
488
  ),
468
- /* @__PURE__ */ jsxRuntime.jsx(
489
+ /* @__PURE__ */ jsxRuntime.jsxs(
469
490
  index.Portal,
470
491
  {
471
492
  isOpen: !!panelGeometry,
472
493
  onRequestClose: hidePanel,
473
494
  style: { zIndex: 9999, elevation: 9999 },
474
- children: panelGeometry && /* @__PURE__ */ jsxRuntime.jsx(
475
- reactNative.Pressable,
476
- {
477
- style: reactNative.StyleSheet.absoluteFillObject,
478
- onPress: () => {
479
- hidePanel();
480
- reactNative.Keyboard.dismiss();
481
- },
482
- children: /* @__PURE__ */ jsxRuntime.jsxs(
483
- reactNative.View,
484
- {
485
- onStartShouldSetResponder: () => true,
486
- onResponderTerminationRequest: () => false,
487
- onLayout: (e) => {
488
- if (__DEV__)
489
- console.log("[AC] panel onLayout (rendered)", e.nativeEvent.layout);
490
- },
491
- style: [
492
- styles.popoverPanel,
493
- {
494
- position: "absolute",
495
- top: panelGeometry.top,
496
- left: panelGeometry.left,
497
- width: panelGeometry.width,
498
- maxHeight: panelGeometry.maxH,
499
- borderColor: colors.border,
500
- backgroundColor: colors.bg,
501
- borderRadius: Math.min(resolvedBorderRadius, 16)
495
+ children: [
496
+ /* @__PURE__ */ jsxRuntime.jsx(
497
+ reactNative.View,
498
+ {
499
+ ref: overlayAnchorRef,
500
+ pointerEvents: "none",
501
+ style: styles.overlayAnchor,
502
+ onLayout: measureOverlayOrigin
503
+ }
504
+ ),
505
+ panelGeometry && /* @__PURE__ */ jsxRuntime.jsx(
506
+ reactNative.Pressable,
507
+ {
508
+ style: reactNative.StyleSheet.absoluteFillObject,
509
+ onPress: () => {
510
+ hidePanel();
511
+ reactNative.Keyboard.dismiss();
512
+ },
513
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
514
+ reactNative.View,
515
+ {
516
+ onStartShouldSetResponder: () => true,
517
+ onResponderTerminationRequest: () => false,
518
+ onLayout: (e) => {
519
+ if (__DEV__)
520
+ console.log("[AC] panel onLayout (rendered)", e.nativeEvent.layout);
502
521
  },
503
- panelStyle
504
- ],
505
- children: [
506
- flatData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
507
- reactNative.FlatList,
522
+ style: [
523
+ styles.popoverPanel,
508
524
  {
509
- data: flatData,
510
- keyExtractor: (_, i) => String(i),
511
- renderItem,
512
- extraData: selectItem,
513
- keyboardShouldPersistTaps: "always",
514
- nestedScrollEnabled: true,
515
- style: { maxHeight: panelGeometry.maxH },
516
- getItemLayout: virtualScrollerOptions ? (_, index) => ({
517
- length: virtualScrollerOptions.itemSize,
518
- offset: virtualScrollerOptions.itemSize * index,
519
- index
520
- }) : void 0
521
- }
522
- ) : (
523
- // Empty state uses the same row layout as a real option
524
- // so forceSelection + "no matches" still feels like a
525
- // list — just with a single non-tappable "no results"
526
- // row. The text is driven by the `emptyMessage` prop so
527
- // consumers can pass a translated string.
528
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.option, styles.emptyRow], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.optionText, { color: colors.emptyText }], children: emptyMessage }) })
529
- ),
530
- panelFooterTemplate?.()
531
- ]
532
- }
533
- )
534
- }
535
- )
525
+ position: "absolute",
526
+ // OVERLAY space (window-space geometry minus the overlay origin).
527
+ top: panelTop,
528
+ left: panelLeft,
529
+ width: panelGeometry.width,
530
+ maxHeight: panelGeometry.maxH,
531
+ borderColor: colors.border,
532
+ backgroundColor: colors.bg,
533
+ borderRadius: panelRadius
534
+ },
535
+ panelStyle
536
+ ],
537
+ children: [
538
+ flatData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
539
+ reactNative.FlatList,
540
+ {
541
+ data: flatData,
542
+ keyExtractor: (_, i) => String(i),
543
+ renderItem,
544
+ extraData: selectItem,
545
+ keyboardShouldPersistTaps: "always",
546
+ nestedScrollEnabled: true,
547
+ style: { maxHeight: panelGeometry.maxH },
548
+ getItemLayout: virtualScrollerOptions ? (_, index) => ({
549
+ length: virtualScrollerOptions.itemSize,
550
+ offset: virtualScrollerOptions.itemSize * index,
551
+ index
552
+ }) : void 0
553
+ }
554
+ ) : (
555
+ // Empty state uses the same row layout as a real option
556
+ // so forceSelection + "no matches" still feels like a
557
+ // list — just with a single non-tappable "no results"
558
+ // row. The text is driven by the `emptyMessage` prop so
559
+ // consumers can pass a translated string.
560
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.option, styles.emptyRow], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.optionText, { color: colors.emptyText }], children: emptyMessage }) })
561
+ ),
562
+ panelFooterTemplate?.()
563
+ ]
564
+ }
565
+ )
566
+ }
567
+ )
568
+ ]
536
569
  }
537
570
  )
538
571
  ]
@@ -593,6 +626,14 @@ const styles = reactNative.StyleSheet.create({
593
626
  fontSize: 12,
594
627
  paddingHorizontal: 2
595
628
  },
629
+ // Zero-size, non-interactive probe at the overlay container's origin.
630
+ overlayAnchor: {
631
+ position: "absolute",
632
+ top: 0,
633
+ left: 0,
634
+ width: 0,
635
+ height: 0
636
+ },
596
637
  popoverPanel: {
597
638
  position: "absolute",
598
639
  borderWidth: 1,