@astryxdesign/core 0.7.8-canary.ffd29c5 → 0.7.8

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 (189) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/dist/BottomSheet/BottomSheetPanel.d.ts +1 -1
  3. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheetPanel.js +30 -14
  5. package/dist/BottomSheet/bottomSheetStack.js +1 -1
  6. package/dist/BottomSheet/useSheetGestures.d.ts +3 -1
  7. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  8. package/dist/BottomSheet/useSheetGestures.js +4 -0
  9. package/dist/CheckboxList/CheckboxList.d.ts +13 -2
  10. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  11. package/dist/CheckboxList/CheckboxList.js +10 -4
  12. package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
  13. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  14. package/dist/CheckboxList/CheckboxListContext.js +2 -1
  15. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  16. package/dist/CheckboxList/CheckboxListItem.js +14 -2
  17. package/dist/CheckboxList/requiredGroup.d.ts +22 -0
  18. package/dist/CheckboxList/requiredGroup.d.ts.map +1 -0
  19. package/dist/CheckboxList/requiredGroup.js +52 -0
  20. package/dist/DateInput/PickerWheel.d.ts +1 -1
  21. package/dist/DateInput/PickerWheel.d.ts.map +1 -1
  22. package/dist/DateInput/PickerWheel.js +27 -6
  23. package/dist/DateInput/Wheel.d.ts +2 -2
  24. package/dist/DateInput/Wheel.d.ts.map +1 -1
  25. package/dist/DateInput/Wheel.js +20 -6
  26. package/dist/DateInput/datePickerTouch.d.ts +13 -0
  27. package/dist/DateInput/datePickerTouch.d.ts.map +1 -0
  28. package/dist/DateInput/datePickerTouch.js +14 -0
  29. package/dist/DateInput/wheelOptions.d.ts +22 -2
  30. package/dist/DateInput/wheelOptions.d.ts.map +1 -1
  31. package/dist/DateInput/wheelOptions.js +14 -2
  32. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  33. package/dist/DateTimeInput/TouchDateTimeField.js +62 -119
  34. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  35. package/dist/HoverCard/useHoverCard.js +6 -1
  36. package/dist/Overlay/Overlay.d.ts.map +1 -1
  37. package/dist/Overlay/Overlay.js +7 -2
  38. package/dist/PowerSearch/PowerSearch.d.ts +4 -2
  39. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  40. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +24 -1
  41. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -1
  42. package/dist/PowerSearch/PowerSearchBottomSheet.js +172 -50
  43. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  44. package/dist/Resizable/ResizeHandle.js +15 -15
  45. package/dist/Resizable/createResizable.d.ts +70 -16
  46. package/dist/Resizable/createResizable.d.ts.map +1 -1
  47. package/dist/Resizable/createResizable.js +180 -22
  48. package/dist/Resizable/separatorAttributes.d.ts +45 -0
  49. package/dist/Resizable/separatorAttributes.d.ts.map +1 -0
  50. package/dist/Resizable/separatorAttributes.js +35 -0
  51. package/dist/Resizable/useResizable.js +2 -2
  52. package/dist/TimeInput/TimeWheels.d.ts +32 -0
  53. package/dist/TimeInput/TimeWheels.d.ts.map +1 -0
  54. package/dist/TimeInput/TimeWheels.js +144 -0
  55. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  56. package/dist/TimeInput/TouchTimeField.js +63 -118
  57. package/dist/TimeInput/timeWheelRules.d.ts +124 -0
  58. package/dist/TimeInput/timeWheelRules.d.ts.map +1 -0
  59. package/dist/TimeInput/timeWheelRules.js +277 -0
  60. package/dist/Tokenizer/TokenizerBottomSheet.js +8 -12
  61. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  62. package/dist/Tooltip/useTooltip.js +6 -0
  63. package/dist/astryx.css +3 -1
  64. package/dist/gestures/GestureHost.d.ts.map +1 -1
  65. package/dist/gestures/GestureHost.js +3 -0
  66. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -1
  67. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +5 -2
  68. package/dist/i18n/generated-english/Resizable/createResizable.generated.d.ts +8 -0
  69. package/dist/i18n/generated-english/Resizable/createResizable.generated.d.ts.map +1 -0
  70. package/dist/i18n/generated-english/Resizable/createResizable.generated.js +13 -0
  71. package/dist/i18n/generated-english/TimeInput/TimeWheels.generated.d.ts +8 -0
  72. package/dist/i18n/generated-english/TimeInput/TimeWheels.generated.d.ts.map +1 -0
  73. package/dist/i18n/generated-english/TimeInput/TimeWheels.generated.js +17 -0
  74. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  75. package/dist/i18n/generated-locales/en.generated.js +5 -2
  76. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  77. package/dist/i18n/generated-locales/pseudo.generated.js +5 -2
  78. package/dist/keyboard/index.d.ts +17 -0
  79. package/dist/keyboard/index.d.ts.map +1 -0
  80. package/dist/keyboard/index.js +19 -0
  81. package/dist/keyboard/keyboardHeight.d.ts +149 -0
  82. package/dist/keyboard/keyboardHeight.d.ts.map +1 -0
  83. package/dist/keyboard/keyboardHeight.js +432 -0
  84. package/dist/keyboard/keyboardLayoutGuide.d.ts +59 -0
  85. package/dist/keyboard/keyboardLayoutGuide.d.ts.map +1 -0
  86. package/dist/keyboard/keyboardLayoutGuide.js +207 -0
  87. package/dist/keyboard/keyboardModel.d.ts +93 -0
  88. package/dist/keyboard/keyboardModel.d.ts.map +1 -0
  89. package/dist/keyboard/keyboardModel.js +220 -0
  90. package/dist/keyboard/rideKeyboard.d.ts +42 -0
  91. package/dist/keyboard/rideKeyboard.d.ts.map +1 -0
  92. package/dist/keyboard/rideKeyboard.js +77 -0
  93. package/dist/keyboard/useMobileKeyboard.d.ts +61 -0
  94. package/dist/keyboard/useMobileKeyboard.d.ts.map +1 -0
  95. package/dist/keyboard/useMobileKeyboard.js +699 -0
  96. package/dist/motion/android/index.d.ts +16 -0
  97. package/dist/motion/android/index.d.ts.map +1 -0
  98. package/dist/motion/android/index.js +18 -0
  99. package/dist/motion/android/keyboard.d.ts +83 -0
  100. package/dist/motion/android/keyboard.d.ts.map +1 -0
  101. package/dist/motion/android/keyboard.js +96 -0
  102. package/dist/motion/uikit/datePicker.d.ts +58 -0
  103. package/dist/motion/uikit/datePicker.d.ts.map +1 -0
  104. package/dist/motion/uikit/datePicker.js +60 -0
  105. package/dist/motion/uikit/index.d.ts +4 -3
  106. package/dist/motion/uikit/index.d.ts.map +1 -1
  107. package/dist/motion/uikit/index.js +4 -3
  108. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  109. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  110. package/dist/utils/interactionOverlay.stylex.js +3 -2
  111. package/dist/utils/layoutViewport.d.ts +25 -0
  112. package/dist/utils/layoutViewport.d.ts.map +1 -0
  113. package/dist/utils/layoutViewport.js +102 -0
  114. package/dist/utils/pressFeedback.d.ts.map +1 -1
  115. package/dist/utils/pressFeedback.js +74 -9
  116. package/dist/utils/pressGesture.d.ts +4 -2
  117. package/dist/utils/pressGesture.d.ts.map +1 -1
  118. package/dist/utils/pressGesture.js +3 -1
  119. package/dist/utils/selectionLock.d.ts +10 -1
  120. package/dist/utils/selectionLock.d.ts.map +1 -1
  121. package/dist/utils/selectionLock.js +31 -5
  122. package/dist/utils/sharedMutationObserver.d.ts +2 -1
  123. package/dist/utils/sharedMutationObserver.d.ts.map +1 -1
  124. package/dist/utils/sharedMutationObserver.js +2 -1
  125. package/dist/utils/timeParser.d.ts +2 -1
  126. package/dist/utils/timeParser.d.ts.map +1 -1
  127. package/dist/utils/timeParser.js +29 -3
  128. package/locales/en.json +21 -9
  129. package/locales/pseudo.json +15 -6
  130. package/package.json +5 -5
  131. package/src/BottomSheet/BottomSheet.doc.mjs +1 -1
  132. package/src/BottomSheet/BottomSheetPanel.tsx +41 -13
  133. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +5 -0
  134. package/src/BottomSheet/bottomSheetStack.ts +1 -1
  135. package/src/BottomSheet/useSheetGestures.ts +6 -0
  136. package/src/CheckboxList/CheckboxList.doc.mjs +7 -0
  137. package/src/CheckboxList/CheckboxList.tsx +34 -2
  138. package/src/CheckboxList/CheckboxListContext.tsx +9 -1
  139. package/src/CheckboxList/CheckboxListItem.tsx +23 -2
  140. package/src/CheckboxList/requiredGroup.ts +77 -0
  141. package/src/DateInput/PickerWheel.tsx +37 -4
  142. package/src/DateInput/Wheel.tsx +30 -3
  143. package/src/DateInput/datePickerTouch.ts +15 -0
  144. package/src/DateInput/wheelOptions.ts +31 -2
  145. package/src/DateTimeInput/TouchDateTimeField.tsx +94 -178
  146. package/src/HoverCard/useHoverCard.tsx +6 -1
  147. package/src/Overlay/Overlay.tsx +7 -2
  148. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  149. package/src/PowerSearch/PowerSearch.tsx +4 -2
  150. package/src/PowerSearch/PowerSearchBottomSheet.tsx +237 -62
  151. package/src/Resizable/ResizeHandle.tsx +18 -26
  152. package/src/Resizable/createResizable.ts +242 -27
  153. package/src/Resizable/separatorAttributes.ts +73 -0
  154. package/src/Resizable/useResizable.ts +2 -2
  155. package/src/TimeInput/TimeWheels.tsx +218 -0
  156. package/src/TimeInput/TouchTimeField.tsx +93 -157
  157. package/src/TimeInput/timeWheelRules.ts +352 -0
  158. package/src/Tokenizer/TokenizerBottomSheet.tsx +8 -12
  159. package/src/Tooltip/useTooltip.tsx +6 -0
  160. package/src/gestures/GestureHost.ts +5 -4
  161. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +5 -2
  162. package/src/i18n/generated-english/Resizable/createResizable.generated.ts +14 -0
  163. package/src/i18n/generated-english/TimeInput/TimeWheels.generated.ts +18 -0
  164. package/src/i18n/generated-locales/en.generated.ts +6 -4
  165. package/src/i18n/generated-locales/pseudo.generated.ts +6 -4
  166. package/src/keyboard/README.md +197 -0
  167. package/src/keyboard/index.ts +48 -0
  168. package/src/keyboard/keyboardHeight.ts +543 -0
  169. package/src/keyboard/keyboardLayoutGuide.ts +266 -0
  170. package/src/keyboard/keyboardModel.ts +301 -0
  171. package/src/keyboard/rideKeyboard.ts +100 -0
  172. package/src/keyboard/useMobileKeyboard.ts +866 -0
  173. package/src/motion/MEASUREMENTS.md +10 -0
  174. package/src/motion/README.md +2 -0
  175. package/src/motion/android/index.ts +18 -0
  176. package/src/motion/android/keyboard.ts +96 -0
  177. package/src/motion/uikit/datePicker.ts +60 -0
  178. package/src/motion/uikit/index.ts +4 -3
  179. package/src/utils/interactionOverlay.stylex.ts +3 -2
  180. package/src/utils/layoutViewport.ts +104 -0
  181. package/src/utils/pressFeedback.ts +99 -21
  182. package/src/utils/pressGesture.ts +4 -2
  183. package/src/utils/selectionLock.ts +40 -6
  184. package/src/utils/sharedMutationObserver.ts +2 -1
  185. package/src/utils/timeParser.ts +40 -3
  186. package/dist/BottomSheet/useMobileKeyboard.d.ts +0 -21
  187. package/dist/BottomSheet/useMobileKeyboard.d.ts.map +0 -1
  188. package/dist/BottomSheet/useMobileKeyboard.js +0 -413
  189. package/src/BottomSheet/useMobileKeyboard.ts +0 -542
@@ -0,0 +1,197 @@
1
+ # On-screen keyboard
2
+
3
+ Core's one source for the on-screen keyboard (`spec:AST-099`,
4
+ `architecture:react-component-runtime` INV11), and the keyboard layout guide
5
+ that times motion with it. Everything here is internal to
6
+ `@astryxdesign/core`: components import it from its defining file, such as
7
+ `../keyboard/keyboardHeight`, and nothing is exported from the package entry.
8
+
9
+ ## The keyboard module (`keyboardHeight.ts`)
10
+
11
+ - **The height (FR2):** `measureKeyboardHeight(window)` is the layout
12
+ viewport's height minus the visual viewport's height times its scale, in CSS
13
+ px. A page pan is not a smaller keyboard, and a pinch zoom is not a keyboard.
14
+ The layout viewport's height is `layoutViewportHeight(window)`
15
+ (`../utils/layoutViewport.ts`), in layout px in every engine: WebKit reports
16
+ `innerHeight` and `innerWidth` in the zoomed visual viewport's px, which
17
+ `innerWidth` matching the visual viewport's width tells apart. A classic
18
+ horizontal scrollbar, which `innerHeight` counts and the visual viewport
19
+ does not, is taken out, so a desktop page wider than its window reads no
20
+ keyboard. BottomSheet's obstruction reads it too.
21
+ - **Where it measures (FR6, FR7, DEC-4):** `isKeyboardMeasurable(window)` is
22
+ true for a top-level document with a visual viewport, a browser with its own
23
+ keyboard geometry API (`navigator.virtualKeyboard`, Chrome on Android)
24
+ included, whose visual viewport shrinks for the keyboard as everywhere
25
+ else. It is decided from capabilities, never from the user agent or the
26
+ pointer. A desktop browser's visual viewport never shrinks for a keyboard,
27
+ so it reads 0; inside an iframe the height is 0. Where the app sets
28
+ `interactive-widget=resizes-content`, Chrome shrinks the layout viewport
29
+ with the keyboard, so the height is 0 there too and nothing rides: the
30
+ browser has made the inset (FR8).
31
+ - **One set of listeners (FR1, INV11):** `subscribeKeyboardHeight(window, fn)`
32
+ delivers every report (the visual viewport's resize and scroll, the window's
33
+ resize, and with `{focus: true}` focus moves, whose input-stream
34
+ subscriptions exist only while such a subscriber does) from one set of listeners per window,
35
+ however many components subscribe, and `getKeyboardHeight(window)` gives a reader the
36
+ height that report measured. No other code in core listens to the visual
37
+ viewport for the keyboard.
38
+ - **Focus (FR4):** `refuseFocusReveal(document, {claim, park, isActive})`
39
+ delivers every focus move a surface claims with `preventScroll`, on the
40
+ capture-phase `blur` before the browser's own focus step, so the browser
41
+ never reveals a field by scrolling the document. Focus that leaves for
42
+ nothing (the keyboard's Done) can be parked so the next tap is a transition
43
+ again. Every caller in a document shares one listener, which lives only
44
+ while a caller does; BottomSheet's hook installs it only under a coarse
45
+ primary pointer.
46
+ - **The browser's own reveal pan (FR4):** `watchRevealPan(window, {owns})`
47
+ is the one building block every keyboard-aware surface uses for a browser
48
+ that pans the visual viewport to a focused field after the keyboard's
49
+ report. The surface calls `report()` on each report that changes the
50
+ height; on a later report, `isRevealPan(height)` says the visual viewport
51
+ has moved down with no touch, document scroll or zoom since, while a text
52
+ field the surface owns has focus, and `putBack()` pans it back without
53
+ scrolling the document, by scrolling into view a probe fixed where the
54
+ visual viewport sat at the report (or the element given, such as a
55
+ full-viewport dialog). Every watch in a document shares one passive
56
+ `touchstart` subscription on the window's input stream, which lives only
57
+ while a surface watches. BottomSheet's hook watches while its sheet is presented
58
+ under a coarse primary pointer; under a fine one it registers no touch
59
+ listener.
60
+ - **The surface hook (FR4, FR5):** `useMobileKeyboard(targetRef, options)`
61
+ (`useMobileKeyboard.ts`) keeps a focused field in a target above the
62
+ keyboard. BottomSheet passes its panel with `{move: 'ride', inset: true}`
63
+ and its suggestion clearance as `offset`, and enables it for a presented
64
+ Tall sheet. The inset goes at the end of the panel's scroll area, its body,
65
+ which `useScrollableArea` marks. The hook gives a fully expanded sheet its
66
+ keyboard scroll range, claims focus moves into it, and puts back a document
67
+ scroll while the page is locked. It attaches through `useAttachment`. It
68
+ returns the inset the keyboard takes at the end of the body's content, and
69
+ `dismiss`, which BottomSheet calls from the drag that starts to move the sheet. The hook itself dismisses the keyboard as its target closes. The sheet lays the inset out after its
70
+ content box's children through a functional style (FR3), committed before
71
+ the reveal scrolls into it. Under a coarse primary pointer, where the
72
+ guide publishes the keyboard's own slide (Gboard's, in Chrome on Android),
73
+ the sheet rides it (FR8). A reveal during the show scrolls the body at once.
74
+ In the same commit it sets the content box so the field sits 4 px above the
75
+ keyboard's top, and the content box then rides the rest of the show's
76
+ curve. Through the hide the inset stays and the content box rides down to
77
+ where the body's scroll rests. At rest the inset drops, the scroll is put
78
+ back and the translate clears in one commit. Under a fine pointer, and in a
79
+ browser without the VirtualKeyboard API (iOS Safari, Firefox for Android),
80
+ nothing of the ride attaches: no guide subscription, and the inset follows
81
+ the reports. Safari's and Firefox's reveals are unchanged.
82
+ - **When the keyboard goes:** the body's scroll goes back to where it was
83
+ when the keyboard came up, within the range left once the inset drops. A
84
+ field that keeps focus, as after iOS's downward keyboard dismissal, is then
85
+ brought into the body's view. Where that dismissal leaves the accessory bar
86
+ up, the visual viewport grows short of full height: the scroll goes back as
87
+ soon as it grows, and a low field is still kept clear of the bar.
88
+
89
+ ## Riding the keyboard
90
+
91
+ Layout follows the height (FR3), through a functional style on your own
92
+ element, so it is right with no animation running; for an element docked at
93
+ the bottom, `lift = height > 0 ? max(0, restingBottom − (innerHeight − height)) : 0`.
94
+ An animation that rides the keyboard is optional polish on top, timed by the
95
+ guide:
96
+
97
+ ```ts
98
+ const guide = getKeyboardLayoutGuide(window);
99
+ const unsubscribe = guide.subscribe(t => {
100
+ rideKeyboard(animator, {y: layoutLift - lift(t.to)}, t);
101
+ });
102
+ ```
103
+
104
+ Each transition is
105
+ `{kind, from, to, start, velocity, animated, predicted, curve}`: heights in
106
+ CSS px, `start` on the document timeline (dated back to Gboard's start for a
107
+ slide Chrome reported, slightly ahead for a hide that starts after a blur),
108
+ and the curve the keyboard moves on: `curve`, Gboard's slide in Chrome on
109
+ Android, values and no motion role (architecture:react-component-runtime
110
+ INV11). `rideKeyboard` moves your element on the compositor from `start` on
111
+ that curve. It lands the element at once when the transition is not animated,
112
+ or when its slide has ended by the call. Hand the translate back to the layout
113
+ once the ride ends (BottomSheet's hook does, in one commit at rest). Under Reduce Motion
114
+ nothing travels with the keyboard
115
+ (design:reduced-motion): the animator's default cross-fades on a touch screen
116
+ and moves at once otherwise. `presentation(time)` gives the height presented
117
+ at any time, for something that appears while the keyboard moves.
118
+
119
+ ## What the page sees
120
+
121
+ - Safari reveals a focused field by scrolling the whole page, so a layout that
122
+ keeps its own content above the keyboard focuses its field with
123
+ `preventScroll` (`refuseFocusReveal`).
124
+ - Firefox for Android reports the keyboard once it is up, and 54 to 143 ms
125
+ later pans the visual viewport to a focused field the keyboard still
126
+ covers. So BottomSheet reveals in the report's own event, and where a
127
+ browser has panned to the field after a report (`watchRevealPan`), it
128
+ lands the field with its own scroller, leaving a smooth reveal under way to
129
+ land it, and only then scrolls the dialog's top back into view; a field it
130
+ cannot bring up keeps the browser's reveal. Every later reveal lands at
131
+ once in the report's frame. Until a browser pans once, the sheet keeps the
132
+ smooth reveal.
133
+ - Chrome on Android (Gboard) animates its own pan to a focused field the
134
+ keyboard still covers, by the keyboard's whole height. It starts about
135
+ 150 ms after the report in Chrome 124, and 100 to 170 ms after it in
136
+ Chrome 133. The page gets no frame until that pan ends, so `watchRevealPan`
137
+ puts it back then. A Tall BottomSheet sets its field 4 px above the
138
+ keyboard's top in the report's own commit, so the field is never covered
139
+ when Chrome checks. Chromium 158 pans the same way when the field stays
140
+ covered, by 312 px with the sheet's reveal on the next frame.
141
+
142
+ ## What the page sees (Chromium 158 with Gboard, Android 15)
143
+
144
+ Measured frame by frame on the emulator, with a marker the page paints on each
145
+ report and Gboard's top read from every recorded frame (`../motion/android/
146
+ keyboard.ts` has the numbers and their sources). The guide reads these reports
147
+ in a browser with the VirtualKeyboard API (`keyboardProfileOf`), and the
148
+ keyboard module measures them from the visual viewport, as in every browser
149
+ (`spec:AST-099` FR8, DEC-4).
150
+
151
+ - Show: Gboard slides up over the page in about 267 ms. Chrome's one `resize`
152
+ of the visual viewport comes just after the slide starts: its first painted
153
+ frame trails Gboard's first moved frame by 14 to 35 ms. The guide dates the
154
+ show back by `androidKeyboard.showReportLagMs` and rides Gboard's show
155
+ curve, joining the slide where it is, so content riding it stays on top of
156
+ the keyboard instead of being covered until the report.
157
+ - Hide: Gboard starts down about `androidKeyboard.hideAfterBlurMs` after the
158
+ blur and leaves in about 167 ms; the `resize` comes mid-slide. The guide
159
+ starts the hide at the blur and takes the `resize` as its confirmation; a
160
+ hide nothing predicted (Back, which keeps the focus) rides from its report,
161
+ dated back `hideReportLagMs`, the lag measured on blurs. Chrome can report
162
+ Back later in the slide, so on Back the content starts down after the
163
+ keyboard does.
164
+ - When focus moves from one field to another through something that brings up
165
+ no keyboard (a popover's container), Chrome reports the keyboard gone and
166
+ back within about 50 ms. A hide reported while a field that gained focus less
167
+ than 150 ms ago still has it waits for the move to settle.
168
+ - `navigator.virtualKeyboard` with `overlaysContent`, the keyboard's own
169
+ geometry, was measured and not used: in 12 shows its `geometrychange` was
170
+ painted 0 to 67 ms after Gboard started (against 14 to 35 ms for the
171
+ visual viewport), it failed to show the keyboard in 4 of 12 shows when set
172
+ on focus (1 of 24 when set as the touch lands), and it hides Chromium's bottom
173
+ toolbar on the keyboard's frame (+56 px of layout).
174
+
175
+ ## Consumers
176
+
177
+ - BottomSheet (`BottomSheet/BottomSheetPanel.tsx`): `useMobileKeyboard`, whose
178
+ inset the content box's `keyboardInset` functional style lays out as the
179
+ content's last box (after its own children, so it adds scroll range in
180
+ Firefox too, which keeps the content box at the body's height); it reveals the
181
+ focused field in the keyboard report's own event, and in Chrome rides the
182
+ content box on Gboard's slides (`rideKeyboard`, from the guide's
183
+ transitions).
184
+
185
+ ## Files
186
+
187
+ | File | What it holds |
188
+ | ------------------------ | --------------------------------------------------------------------------------------------------------------------- |
189
+ | `keyboardHeight.ts` | The keyboard module: the height, its listeners, the focus routes. |
190
+ | `useMobileKeyboard.ts` | Keeps a focused field in a target above the keyboard: the inset, the reveal, the ride and the dismiss. |
191
+ | `keyboardModel.ts` | The clock-free core of the guide: transitions from keyboard reports and focus changes. |
192
+ | `keyboardLayoutGuide.ts` | One guide per window, fed by the keyboard module: the verification timer, the focus handoff. |
193
+ | `rideKeyboard.ts` | Moves an element with the keyboard on the curve its transition publishes, or at once (tests: `rideKeyboard.test.ts`). |
194
+ | `index.ts` | Entry point. |
195
+
196
+ The timing constants live in `../motion/android/keyboard.ts` (Chrome with
197
+ Gboard).
@@ -0,0 +1,48 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file index.ts
5
+ * @input keyboardHeight.ts, keyboardLayoutGuide.ts, keyboardModel.ts and
6
+ * rideKeyboard.ts
7
+ * @output Re-exports the on-screen keyboard module, the keyboard layout
8
+ * guide and rideKeyboard, with their types
9
+ * @position Entry of the keyboard module. It is internal to core, and the
10
+ * package entry point exports nothing here.
11
+ *
12
+ * SYNC: When modified, update /packages/core/src/keyboard/README.md
13
+ */
14
+
15
+ export {
16
+ findTextEntryControl,
17
+ getKeyboardHeight,
18
+ isKeyboardMeasurable,
19
+ isTextEntryControl,
20
+ measureKeyboardHeight,
21
+ refuseFocusReveal,
22
+ subscribeKeyboardHeight,
23
+ watchRevealPan,
24
+ type KeyboardHeightEvent,
25
+ type RefuseFocusRevealOptions,
26
+ type RevealPanWatch,
27
+ type WatchRevealPanOptions,
28
+ } from './keyboardHeight';
29
+ export {
30
+ bringsUpKeyboard,
31
+ getKeyboardLayoutGuide,
32
+ keyboardProfileOf,
33
+ type KeyboardLayoutGuide,
34
+ } from './keyboardLayoutGuide';
35
+ export {rideKeyboard} from './rideKeyboard';
36
+ export {
37
+ useMobileKeyboard,
38
+ type MobileKeyboard,
39
+ type MobileKeyboardOptions,
40
+ } from './useMobileKeyboard';
41
+ export {
42
+ createKeyboardModel,
43
+ type KeyboardCurve,
44
+ type KeyboardModel,
45
+ type KeyboardProfile,
46
+ type KeyboardTransition,
47
+ type KeyboardTransitionKind,
48
+ } from './keyboardModel';