@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.
- package/CHANGELOG.md +132 -0
- package/dist/BottomSheet/BottomSheetPanel.d.ts +1 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +30 -14
- package/dist/BottomSheet/bottomSheetStack.js +1 -1
- package/dist/BottomSheet/useSheetGestures.d.ts +3 -1
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +4 -0
- package/dist/CheckboxList/CheckboxList.d.ts +13 -2
- package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxList.js +10 -4
- package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
- package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListContext.js +2 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +14 -2
- package/dist/CheckboxList/requiredGroup.d.ts +22 -0
- package/dist/CheckboxList/requiredGroup.d.ts.map +1 -0
- package/dist/CheckboxList/requiredGroup.js +52 -0
- package/dist/DateInput/PickerWheel.d.ts +1 -1
- package/dist/DateInput/PickerWheel.d.ts.map +1 -1
- package/dist/DateInput/PickerWheel.js +27 -6
- package/dist/DateInput/Wheel.d.ts +2 -2
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +20 -6
- package/dist/DateInput/datePickerTouch.d.ts +13 -0
- package/dist/DateInput/datePickerTouch.d.ts.map +1 -0
- package/dist/DateInput/datePickerTouch.js +14 -0
- package/dist/DateInput/wheelOptions.d.ts +22 -2
- package/dist/DateInput/wheelOptions.d.ts.map +1 -1
- package/dist/DateInput/wheelOptions.js +14 -2
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +62 -119
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +6 -1
- package/dist/Overlay/Overlay.d.ts.map +1 -1
- package/dist/Overlay/Overlay.js +7 -2
- package/dist/PowerSearch/PowerSearch.d.ts +4 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +24 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.js +172 -50
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +15 -15
- package/dist/Resizable/createResizable.d.ts +70 -16
- package/dist/Resizable/createResizable.d.ts.map +1 -1
- package/dist/Resizable/createResizable.js +180 -22
- package/dist/Resizable/separatorAttributes.d.ts +45 -0
- package/dist/Resizable/separatorAttributes.d.ts.map +1 -0
- package/dist/Resizable/separatorAttributes.js +35 -0
- package/dist/Resizable/useResizable.js +2 -2
- package/dist/TimeInput/TimeWheels.d.ts +32 -0
- package/dist/TimeInput/TimeWheels.d.ts.map +1 -0
- package/dist/TimeInput/TimeWheels.js +144 -0
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
- package/dist/TimeInput/TouchTimeField.js +63 -118
- package/dist/TimeInput/timeWheelRules.d.ts +124 -0
- package/dist/TimeInput/timeWheelRules.d.ts.map +1 -0
- package/dist/TimeInput/timeWheelRules.js +277 -0
- package/dist/Tokenizer/TokenizerBottomSheet.js +8 -12
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +6 -0
- package/dist/astryx.css +3 -1
- package/dist/gestures/GestureHost.d.ts.map +1 -1
- package/dist/gestures/GestureHost.js +3 -0
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +5 -2
- package/dist/i18n/generated-english/Resizable/createResizable.generated.d.ts +8 -0
- package/dist/i18n/generated-english/Resizable/createResizable.generated.d.ts.map +1 -0
- package/dist/i18n/generated-english/Resizable/createResizable.generated.js +13 -0
- package/dist/i18n/generated-english/TimeInput/TimeWheels.generated.d.ts +8 -0
- package/dist/i18n/generated-english/TimeInput/TimeWheels.generated.d.ts.map +1 -0
- package/dist/i18n/generated-english/TimeInput/TimeWheels.generated.js +17 -0
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +5 -2
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +5 -2
- package/dist/keyboard/index.d.ts +17 -0
- package/dist/keyboard/index.d.ts.map +1 -0
- package/dist/keyboard/index.js +19 -0
- package/dist/keyboard/keyboardHeight.d.ts +149 -0
- package/dist/keyboard/keyboardHeight.d.ts.map +1 -0
- package/dist/keyboard/keyboardHeight.js +432 -0
- package/dist/keyboard/keyboardLayoutGuide.d.ts +59 -0
- package/dist/keyboard/keyboardLayoutGuide.d.ts.map +1 -0
- package/dist/keyboard/keyboardLayoutGuide.js +207 -0
- package/dist/keyboard/keyboardModel.d.ts +93 -0
- package/dist/keyboard/keyboardModel.d.ts.map +1 -0
- package/dist/keyboard/keyboardModel.js +220 -0
- package/dist/keyboard/rideKeyboard.d.ts +42 -0
- package/dist/keyboard/rideKeyboard.d.ts.map +1 -0
- package/dist/keyboard/rideKeyboard.js +77 -0
- package/dist/keyboard/useMobileKeyboard.d.ts +61 -0
- package/dist/keyboard/useMobileKeyboard.d.ts.map +1 -0
- package/dist/keyboard/useMobileKeyboard.js +699 -0
- package/dist/motion/android/index.d.ts +16 -0
- package/dist/motion/android/index.d.ts.map +1 -0
- package/dist/motion/android/index.js +18 -0
- package/dist/motion/android/keyboard.d.ts +83 -0
- package/dist/motion/android/keyboard.d.ts.map +1 -0
- package/dist/motion/android/keyboard.js +96 -0
- package/dist/motion/uikit/datePicker.d.ts +58 -0
- package/dist/motion/uikit/datePicker.d.ts.map +1 -0
- package/dist/motion/uikit/datePicker.js +60 -0
- package/dist/motion/uikit/index.d.ts +4 -3
- package/dist/motion/uikit/index.d.ts.map +1 -1
- package/dist/motion/uikit/index.js +4 -3
- package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +3 -2
- package/dist/utils/layoutViewport.d.ts +25 -0
- package/dist/utils/layoutViewport.d.ts.map +1 -0
- package/dist/utils/layoutViewport.js +102 -0
- package/dist/utils/pressFeedback.d.ts.map +1 -1
- package/dist/utils/pressFeedback.js +74 -9
- package/dist/utils/pressGesture.d.ts +4 -2
- package/dist/utils/pressGesture.d.ts.map +1 -1
- package/dist/utils/pressGesture.js +3 -1
- package/dist/utils/selectionLock.d.ts +10 -1
- package/dist/utils/selectionLock.d.ts.map +1 -1
- package/dist/utils/selectionLock.js +31 -5
- package/dist/utils/sharedMutationObserver.d.ts +2 -1
- package/dist/utils/sharedMutationObserver.d.ts.map +1 -1
- package/dist/utils/sharedMutationObserver.js +2 -1
- package/dist/utils/timeParser.d.ts +2 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +29 -3
- package/locales/en.json +21 -9
- package/locales/pseudo.json +15 -6
- package/package.json +5 -5
- package/src/BottomSheet/BottomSheet.doc.mjs +1 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +41 -13
- package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +5 -0
- package/src/BottomSheet/bottomSheetStack.ts +1 -1
- package/src/BottomSheet/useSheetGestures.ts +6 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +7 -0
- package/src/CheckboxList/CheckboxList.tsx +34 -2
- package/src/CheckboxList/CheckboxListContext.tsx +9 -1
- package/src/CheckboxList/CheckboxListItem.tsx +23 -2
- package/src/CheckboxList/requiredGroup.ts +77 -0
- package/src/DateInput/PickerWheel.tsx +37 -4
- package/src/DateInput/Wheel.tsx +30 -3
- package/src/DateInput/datePickerTouch.ts +15 -0
- package/src/DateInput/wheelOptions.ts +31 -2
- package/src/DateTimeInput/TouchDateTimeField.tsx +94 -178
- package/src/HoverCard/useHoverCard.tsx +6 -1
- package/src/Overlay/Overlay.tsx +7 -2
- package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
- package/src/PowerSearch/PowerSearch.tsx +4 -2
- package/src/PowerSearch/PowerSearchBottomSheet.tsx +237 -62
- package/src/Resizable/ResizeHandle.tsx +18 -26
- package/src/Resizable/createResizable.ts +242 -27
- package/src/Resizable/separatorAttributes.ts +73 -0
- package/src/Resizable/useResizable.ts +2 -2
- package/src/TimeInput/TimeWheels.tsx +218 -0
- package/src/TimeInput/TouchTimeField.tsx +93 -157
- package/src/TimeInput/timeWheelRules.ts +352 -0
- package/src/Tokenizer/TokenizerBottomSheet.tsx +8 -12
- package/src/Tooltip/useTooltip.tsx +6 -0
- package/src/gestures/GestureHost.ts +5 -4
- package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +5 -2
- package/src/i18n/generated-english/Resizable/createResizable.generated.ts +14 -0
- package/src/i18n/generated-english/TimeInput/TimeWheels.generated.ts +18 -0
- package/src/i18n/generated-locales/en.generated.ts +6 -4
- package/src/i18n/generated-locales/pseudo.generated.ts +6 -4
- package/src/keyboard/README.md +197 -0
- package/src/keyboard/index.ts +48 -0
- package/src/keyboard/keyboardHeight.ts +543 -0
- package/src/keyboard/keyboardLayoutGuide.ts +266 -0
- package/src/keyboard/keyboardModel.ts +301 -0
- package/src/keyboard/rideKeyboard.ts +100 -0
- package/src/keyboard/useMobileKeyboard.ts +866 -0
- package/src/motion/MEASUREMENTS.md +10 -0
- package/src/motion/README.md +2 -0
- package/src/motion/android/index.ts +18 -0
- package/src/motion/android/keyboard.ts +96 -0
- package/src/motion/uikit/datePicker.ts +60 -0
- package/src/motion/uikit/index.ts +4 -3
- package/src/utils/interactionOverlay.stylex.ts +3 -2
- package/src/utils/layoutViewport.ts +104 -0
- package/src/utils/pressFeedback.ts +99 -21
- package/src/utils/pressGesture.ts +4 -2
- package/src/utils/selectionLock.ts +40 -6
- package/src/utils/sharedMutationObserver.ts +2 -1
- package/src/utils/timeParser.ts +40 -3
- package/dist/BottomSheet/useMobileKeyboard.d.ts +0 -21
- package/dist/BottomSheet/useMobileKeyboard.d.ts.map +0 -1
- package/dist/BottomSheet/useMobileKeyboard.js +0 -413
- 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';
|