@radix-ng/primitives 1.0.0-beta.4 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/composite/README.md +3 -0
- package/fesm2022/radix-ng-primitives-accordion.mjs +12 -36
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +33 -18
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-composite.mjs +515 -0
- package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-core.mjs +7 -0
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dialog.mjs +54 -12
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-drawer.mjs +442 -2
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-editable.mjs +12 -7
- package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +294 -8
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +9 -0
- package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +71 -20
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +68 -36
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +281 -88
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +7 -2
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +117 -35
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +73 -65
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +77 -36
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +40 -8
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +56 -25
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +62 -37
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +259 -28
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-stepper.mjs +11 -7
- package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +10 -5
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +64 -30
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +69 -19
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle.mjs +37 -13
- package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +50 -24
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tooltip.mjs +180 -35
- package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
- package/navigation-menu/README.md +5 -2
- package/package.json +5 -1
- package/types/radix-ng-primitives-accordion.d.ts +9 -13
- package/types/radix-ng-primitives-checkbox.d.ts +27 -15
- package/types/radix-ng-primitives-composite.d.ts +152 -0
- package/types/radix-ng-primitives-core.d.ts +2 -0
- package/types/radix-ng-primitives-dialog.d.ts +13 -2
- package/types/radix-ng-primitives-drawer.d.ts +40 -2
- package/types/radix-ng-primitives-editable.d.ts +11 -5
- package/types/radix-ng-primitives-floating-focus-manager.d.ts +113 -16
- package/types/radix-ng-primitives-menu.d.ts +13 -5
- package/types/radix-ng-primitives-menubar.d.ts +10 -5
- package/types/radix-ng-primitives-navigation-menu.d.ts +65 -33
- package/types/radix-ng-primitives-number-field.d.ts +8 -3
- package/types/radix-ng-primitives-popover.d.ts +26 -10
- package/types/radix-ng-primitives-popper.d.ts +1 -0
- package/types/radix-ng-primitives-radio.d.ts +22 -13
- package/types/radix-ng-primitives-roving-focus.d.ts +15 -1
- package/types/radix-ng-primitives-scroll-area.d.ts +4 -1
- package/types/radix-ng-primitives-select.d.ts +16 -20
- package/types/radix-ng-primitives-slider.d.ts +60 -9
- package/types/radix-ng-primitives-stepper.d.ts +11 -4
- package/types/radix-ng-primitives-switch.d.ts +10 -4
- package/types/radix-ng-primitives-tabs.d.ts +20 -11
- package/types/radix-ng-primitives-toggle-group.d.ts +34 -17
- package/types/radix-ng-primitives-toggle.d.ts +14 -7
- package/types/radix-ng-primitives-toolbar.d.ts +22 -14
- package/types/radix-ng-primitives-tooltip.d.ts +38 -14
|
@@ -78,7 +78,8 @@ const context = () => {
|
|
|
78
78
|
nestedDrawerOpen: root.nestedDrawerOpen,
|
|
79
79
|
nestedDrawerCount: root.nestedDrawerCount,
|
|
80
80
|
frontmostHeight: root.frontmostHeight,
|
|
81
|
-
reportPopupHeight: (height) => root.popupHeight.set(height)
|
|
81
|
+
reportPopupHeight: (height) => root.popupHeight.set(height),
|
|
82
|
+
open: root.open
|
|
82
83
|
};
|
|
83
84
|
};
|
|
84
85
|
/**
|
|
@@ -974,6 +975,442 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
974
975
|
}]
|
|
975
976
|
}] });
|
|
976
977
|
|
|
978
|
+
const KEYBOARD_RESIZE_THRESHOLD = 60;
|
|
979
|
+
const KEYBOARD_VISIBILITY_MARGIN = 16;
|
|
980
|
+
const KEYBOARD_SCROLL_SLACK = 48;
|
|
981
|
+
const INPUT_TAP_MOVE_THRESHOLD = 10;
|
|
982
|
+
const INPUT_TAP_HIT_SLOP = 16;
|
|
983
|
+
const KEYBOARD_INPUT_TYPES = new Set(['email', 'number', 'password', 'search', 'tel', 'text', 'url']);
|
|
984
|
+
const KEYBOARD_TAP_BLOCKED = Symbol('KeyboardTapBlocked');
|
|
985
|
+
/**
|
|
986
|
+
* Provides mobile virtual-keyboard handling for bottom-sheet drawers with form fields.
|
|
987
|
+
*
|
|
988
|
+
* Put it on the drawer viewport that contains the popup. The directive writes
|
|
989
|
+
* `--drawer-keyboard-inset` to the host, keeps the focused keyboard input visible when
|
|
990
|
+
* `visualViewport` shrinks, adds temporary scroll slack to the nearest drawer scroller, and uses
|
|
991
|
+
* synchronous tap-to-focus on touch devices so iOS opens the software keyboard reliably.
|
|
992
|
+
*/
|
|
993
|
+
class RdxDrawerVirtualKeyboardProvider {
|
|
994
|
+
constructor() {
|
|
995
|
+
this.drawerContext = injectRdxDrawerRootContext();
|
|
996
|
+
this.elementRef = inject(ElementRef);
|
|
997
|
+
this.destroyRef = inject(DestroyRef);
|
|
998
|
+
this.element = this.elementRef.nativeElement;
|
|
999
|
+
this.pendingKeyboardFocusMoved = false;
|
|
1000
|
+
this.keyboardTouchStart = null;
|
|
1001
|
+
this.focusedKeyboardTarget = null;
|
|
1002
|
+
this.keyboardScrollAdjustment = null;
|
|
1003
|
+
this.keyboardFocusFrame = 0;
|
|
1004
|
+
effect((onCleanup) => {
|
|
1005
|
+
const open = this.drawerContext.open();
|
|
1006
|
+
const nestedDrawerOpen = this.drawerContext.nestedDrawerOpen();
|
|
1007
|
+
if (!open || nestedDrawerOpen) {
|
|
1008
|
+
untracked(() => this.clearFocusedKeyboardTarget());
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
const doc = this.element.ownerDocument;
|
|
1012
|
+
const win = doc.defaultView;
|
|
1013
|
+
if (!win) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
const handleFocusIn = (event) => {
|
|
1017
|
+
if (this.captureFocusedKeyboardTarget(event.target)) {
|
|
1018
|
+
this.scheduleKeyboardFocusAlignment();
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
const handleFocusOut = (event) => {
|
|
1022
|
+
if (this.captureFocusedKeyboardTarget(event.relatedTarget)) {
|
|
1023
|
+
this.scheduleKeyboardFocusAlignment();
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
this.clearFocusedKeyboardTarget();
|
|
1027
|
+
};
|
|
1028
|
+
const handleViewportUpdate = () => {
|
|
1029
|
+
if (this.focusedKeyboardTarget || this.captureFocusedKeyboardTarget(doc.activeElement)) {
|
|
1030
|
+
this.scheduleKeyboardFocusAlignment();
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
const visualViewport = win.visualViewport;
|
|
1034
|
+
doc.addEventListener('focusin', handleFocusIn, true);
|
|
1035
|
+
doc.addEventListener('focusout', handleFocusOut, true);
|
|
1036
|
+
visualViewport?.addEventListener('resize', handleViewportUpdate);
|
|
1037
|
+
visualViewport?.addEventListener('scroll', handleViewportUpdate);
|
|
1038
|
+
if (this.captureFocusedKeyboardTarget(doc.activeElement)) {
|
|
1039
|
+
this.scheduleKeyboardFocusAlignment();
|
|
1040
|
+
}
|
|
1041
|
+
onCleanup(() => {
|
|
1042
|
+
doc.removeEventListener('focusin', handleFocusIn, true);
|
|
1043
|
+
doc.removeEventListener('focusout', handleFocusOut, true);
|
|
1044
|
+
visualViewport?.removeEventListener('resize', handleViewportUpdate);
|
|
1045
|
+
visualViewport?.removeEventListener('scroll', handleViewportUpdate);
|
|
1046
|
+
this.clearFocusedKeyboardTarget();
|
|
1047
|
+
this.element.style.removeProperty('--drawer-keyboard-inset');
|
|
1048
|
+
});
|
|
1049
|
+
});
|
|
1050
|
+
this.destroyRef.onDestroy(() => {
|
|
1051
|
+
this.cancelKeyboardFocusFrame();
|
|
1052
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1053
|
+
this.element.style.removeProperty('--drawer-keyboard-inset');
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
onTouchStart(event) {
|
|
1057
|
+
if (!this.drawerContext.open() || this.drawerContext.nestedDrawerOpen()) {
|
|
1058
|
+
this.resetTouchTrackingState();
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
const touch = event.touches[0];
|
|
1062
|
+
if (!touch) {
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1065
|
+
this.pendingKeyboardFocusMoved = false;
|
|
1066
|
+
this.keyboardTouchStart = { x: touch.clientX, y: touch.clientY };
|
|
1067
|
+
}
|
|
1068
|
+
onTouchMove(event) {
|
|
1069
|
+
const touch = event.touches[0];
|
|
1070
|
+
const touchStart = this.keyboardTouchStart;
|
|
1071
|
+
if (!touch || !touchStart || this.pendingKeyboardFocusMoved) {
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
if (Math.abs(touch.clientX - touchStart.x) > INPUT_TAP_MOVE_THRESHOLD ||
|
|
1075
|
+
Math.abs(touch.clientY - touchStart.y) > INPUT_TAP_MOVE_THRESHOLD) {
|
|
1076
|
+
this.pendingKeyboardFocusMoved = true;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
onTouchEnd(event) {
|
|
1080
|
+
if (!this.drawerContext.open() ||
|
|
1081
|
+
this.drawerContext.nestedDrawerOpen() ||
|
|
1082
|
+
!this.keyboardTouchStart ||
|
|
1083
|
+
this.pendingKeyboardFocusMoved) {
|
|
1084
|
+
this.resetTouchTrackingState();
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
const touch = event.changedTouches[0] ?? event.touches[0];
|
|
1088
|
+
const doc = this.element.ownerDocument;
|
|
1089
|
+
const nativeEventTarget = event.target;
|
|
1090
|
+
const pointTarget = touch ? resolveKeyboardTouchTargetFromPoint(doc, touch.clientX, touch.clientY) : null;
|
|
1091
|
+
if (pointTarget === KEYBOARD_TAP_BLOCKED) {
|
|
1092
|
+
this.resetTouchTrackingState();
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
const keyboardTarget = touch && (pointTarget ?? resolveKeyboardTouchTarget(nativeEventTarget));
|
|
1096
|
+
if (keyboardTarget &&
|
|
1097
|
+
(!this.element.contains(keyboardTarget.focusTarget) || !this.element.contains(keyboardTarget.clickTarget))) {
|
|
1098
|
+
this.resetTouchTrackingState();
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
if (!keyboardTarget || !touch) {
|
|
1102
|
+
this.resetTouchTrackingState();
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
const win = keyboardTarget.focusTarget.ownerDocument.defaultView;
|
|
1106
|
+
if (!win || (win.visualViewport && win.visualViewport.scale !== 1)) {
|
|
1107
|
+
this.resetTouchTrackingState();
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
if (doc.activeElement === keyboardTarget.focusTarget && isKeyboardVisualViewportOpen(win)) {
|
|
1111
|
+
this.resetTouchTrackingState();
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
event.preventDefault();
|
|
1115
|
+
focusKeyboardInputWithoutPageScroll(keyboardTarget.focusTarget);
|
|
1116
|
+
dispatchKeyboardClick(keyboardTarget.clickTarget, touch);
|
|
1117
|
+
this.resetTouchTrackingState();
|
|
1118
|
+
}
|
|
1119
|
+
resetTouchTrackingState() {
|
|
1120
|
+
this.pendingKeyboardFocusMoved = false;
|
|
1121
|
+
this.keyboardTouchStart = null;
|
|
1122
|
+
}
|
|
1123
|
+
captureFocusedKeyboardTarget(eventTarget) {
|
|
1124
|
+
if (this.drawerContext.nestedDrawerOpen()) {
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
const target = resolveKeyboardInputTarget(eventTarget);
|
|
1128
|
+
if (!target || !this.element.contains(target)) {
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
this.focusedKeyboardTarget = target;
|
|
1132
|
+
return true;
|
|
1133
|
+
}
|
|
1134
|
+
alignFocusedKeyboardTarget() {
|
|
1135
|
+
const target = this.focusedKeyboardTarget;
|
|
1136
|
+
const win = this.element.ownerDocument.defaultView;
|
|
1137
|
+
if (!win || this.drawerContext.nestedDrawerOpen() || !target || !this.element.contains(target)) {
|
|
1138
|
+
this.resetDrawerKeyboardInset();
|
|
1139
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
const keyboardViewport = getKeyboardVisualViewport(win);
|
|
1143
|
+
if (!keyboardViewport) {
|
|
1144
|
+
this.resetDrawerKeyboardInset();
|
|
1145
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
this.setDrawerKeyboardInset(getDrawerKeyboardInset(win, keyboardViewport));
|
|
1149
|
+
const scrollTarget = findKeyboardScrollTarget(target, this.element);
|
|
1150
|
+
if (!scrollTarget || !scrollTarget.isConnected || !this.element.contains(scrollTarget)) {
|
|
1151
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const scrollTargetRect = scrollTarget.getBoundingClientRect();
|
|
1155
|
+
const clippedBottom = Math.min(scrollTargetRect.bottom, keyboardViewport.bottom);
|
|
1156
|
+
const overlap = Math.max(0, scrollTargetRect.bottom - keyboardViewport.bottom);
|
|
1157
|
+
this.setKeyboardScrollSlack(scrollTarget, overlap > 0 ? overlap + KEYBOARD_SCROLL_SLACK : 0);
|
|
1158
|
+
const maxScrollTop = Math.max(0, scrollTarget.scrollHeight - scrollTarget.clientHeight);
|
|
1159
|
+
if (maxScrollTop <= 0) {
|
|
1160
|
+
return;
|
|
1161
|
+
}
|
|
1162
|
+
const clippedTop = Math.max(scrollTargetRect.top, keyboardViewport.top);
|
|
1163
|
+
const visibleTop = clippedTop + KEYBOARD_VISIBILITY_MARGIN;
|
|
1164
|
+
const visibleBottom = clippedBottom - KEYBOARD_VISIBILITY_MARGIN;
|
|
1165
|
+
if (visibleBottom <= visibleTop) {
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
const targetRect = target.getBoundingClientRect();
|
|
1169
|
+
const targetCenter = (targetRect.top + targetRect.bottom) / 2;
|
|
1170
|
+
const visibleCenter = (visibleTop + visibleBottom) / 2;
|
|
1171
|
+
const nextScrollTop = scrollTarget.scrollTop + targetCenter - visibleCenter;
|
|
1172
|
+
scrollTarget.scrollTo({
|
|
1173
|
+
top: clamp(nextScrollTop, 0, maxScrollTop),
|
|
1174
|
+
behavior: prefersReducedMotion(win) ? 'auto' : 'smooth'
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
scheduleKeyboardFocusAlignment() {
|
|
1178
|
+
this.cancelKeyboardFocusFrame();
|
|
1179
|
+
this.keyboardFocusFrame = requestAnimationFrame(() => {
|
|
1180
|
+
this.keyboardFocusFrame = 0;
|
|
1181
|
+
this.alignFocusedKeyboardTarget();
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
cancelKeyboardFocusFrame() {
|
|
1185
|
+
if (this.keyboardFocusFrame) {
|
|
1186
|
+
cancelAnimationFrame(this.keyboardFocusFrame);
|
|
1187
|
+
this.keyboardFocusFrame = 0;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
clearFocusedKeyboardTarget() {
|
|
1191
|
+
this.focusedKeyboardTarget = null;
|
|
1192
|
+
this.resetDrawerKeyboardInset();
|
|
1193
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1194
|
+
this.cancelKeyboardFocusFrame();
|
|
1195
|
+
}
|
|
1196
|
+
setDrawerKeyboardInset(inset) {
|
|
1197
|
+
this.element.style.setProperty('--drawer-keyboard-inset', `${Math.max(0, Math.ceil(inset))}px`);
|
|
1198
|
+
}
|
|
1199
|
+
resetDrawerKeyboardInset() {
|
|
1200
|
+
this.setDrawerKeyboardInset(0);
|
|
1201
|
+
}
|
|
1202
|
+
setKeyboardScrollSlack(element, slack) {
|
|
1203
|
+
const roundedSlack = Math.max(0, Math.ceil(slack));
|
|
1204
|
+
let adjustment = this.keyboardScrollAdjustment;
|
|
1205
|
+
if (adjustment && !adjustment.element.isConnected) {
|
|
1206
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1207
|
+
adjustment = null;
|
|
1208
|
+
}
|
|
1209
|
+
if (roundedSlack === 0) {
|
|
1210
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
if (adjustment && adjustment.element !== element) {
|
|
1214
|
+
this.restoreKeyboardScrollAdjustment();
|
|
1215
|
+
adjustment = null;
|
|
1216
|
+
}
|
|
1217
|
+
if (!adjustment) {
|
|
1218
|
+
const styles = getComputedStyle(element);
|
|
1219
|
+
adjustment = {
|
|
1220
|
+
element,
|
|
1221
|
+
overflowAnchor: element.style.overflowAnchor,
|
|
1222
|
+
paddingBottom: element.style.paddingBottom,
|
|
1223
|
+
scrollPaddingBottom: element.style.scrollPaddingBottom,
|
|
1224
|
+
computedPaddingBottom: Number.parseFloat(styles.paddingBottom) || 0,
|
|
1225
|
+
computedScrollPaddingBottom: Number.parseFloat(styles.scrollPaddingBottom) || 0
|
|
1226
|
+
};
|
|
1227
|
+
this.keyboardScrollAdjustment = adjustment;
|
|
1228
|
+
}
|
|
1229
|
+
element.style.overflowAnchor = 'none';
|
|
1230
|
+
element.style.paddingBottom = `${adjustment.computedPaddingBottom + roundedSlack}px`;
|
|
1231
|
+
element.style.scrollPaddingBottom = `${adjustment.computedScrollPaddingBottom + KEYBOARD_VISIBILITY_MARGIN}px`;
|
|
1232
|
+
}
|
|
1233
|
+
restoreKeyboardScrollAdjustment() {
|
|
1234
|
+
const adjustment = this.keyboardScrollAdjustment;
|
|
1235
|
+
if (!adjustment) {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
adjustment.element.style.overflowAnchor = adjustment.overflowAnchor;
|
|
1239
|
+
adjustment.element.style.paddingBottom = adjustment.paddingBottom;
|
|
1240
|
+
adjustment.element.style.scrollPaddingBottom = adjustment.scrollPaddingBottom;
|
|
1241
|
+
this.keyboardScrollAdjustment = null;
|
|
1242
|
+
}
|
|
1243
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerVirtualKeyboardProvider, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1244
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerVirtualKeyboardProvider, isStandalone: true, selector: "[rdxDrawerVirtualKeyboardProvider]", host: { listeners: { "touchstart": "onTouchStart($event)", "touchmove": "onTouchMove($event)", "touchend": "onTouchEnd($event)", "touchcancel": "resetTouchTrackingState()" } }, exportAs: ["rdxDrawerVirtualKeyboardProvider"], ngImport: i0 }); }
|
|
1245
|
+
}
|
|
1246
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerVirtualKeyboardProvider, decorators: [{
|
|
1247
|
+
type: Directive,
|
|
1248
|
+
args: [{
|
|
1249
|
+
selector: '[rdxDrawerVirtualKeyboardProvider]',
|
|
1250
|
+
exportAs: 'rdxDrawerVirtualKeyboardProvider',
|
|
1251
|
+
host: {
|
|
1252
|
+
'(touchstart)': 'onTouchStart($event)',
|
|
1253
|
+
'(touchmove)': 'onTouchMove($event)',
|
|
1254
|
+
'(touchend)': 'onTouchEnd($event)',
|
|
1255
|
+
'(touchcancel)': 'resetTouchTrackingState()'
|
|
1256
|
+
}
|
|
1257
|
+
}]
|
|
1258
|
+
}], ctorParameters: () => [] });
|
|
1259
|
+
function isHTMLElement(target) {
|
|
1260
|
+
return target instanceof HTMLElement;
|
|
1261
|
+
}
|
|
1262
|
+
function isKeyboardInputElement(element) {
|
|
1263
|
+
if (element.isContentEditable) {
|
|
1264
|
+
return true;
|
|
1265
|
+
}
|
|
1266
|
+
if (element instanceof HTMLTextAreaElement) {
|
|
1267
|
+
return !element.matches(':disabled');
|
|
1268
|
+
}
|
|
1269
|
+
if (element instanceof HTMLInputElement && KEYBOARD_INPUT_TYPES.has(element.type)) {
|
|
1270
|
+
return !element.matches(':disabled');
|
|
1271
|
+
}
|
|
1272
|
+
return false;
|
|
1273
|
+
}
|
|
1274
|
+
function resolveKeyboardInputTarget(target) {
|
|
1275
|
+
if (!isHTMLElement(target)) {
|
|
1276
|
+
return null;
|
|
1277
|
+
}
|
|
1278
|
+
if (isKeyboardInputElement(target)) {
|
|
1279
|
+
return target.isContentEditable ? getContentEditableHost(target) : target;
|
|
1280
|
+
}
|
|
1281
|
+
const label = target.closest('label');
|
|
1282
|
+
const control = label?.control ?? null;
|
|
1283
|
+
return isHTMLElement(control) && isKeyboardInputElement(control) ? control : null;
|
|
1284
|
+
}
|
|
1285
|
+
function resolveKeyboardTouchTarget(target) {
|
|
1286
|
+
const focusTarget = resolveKeyboardInputTarget(target);
|
|
1287
|
+
if (!focusTarget) {
|
|
1288
|
+
return null;
|
|
1289
|
+
}
|
|
1290
|
+
return {
|
|
1291
|
+
focusTarget,
|
|
1292
|
+
clickTarget: isHTMLElement(target) ? target : focusTarget
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
function getContentEditableHost(element) {
|
|
1296
|
+
let host = element;
|
|
1297
|
+
while (host.parentElement?.isContentEditable) {
|
|
1298
|
+
host = host.parentElement;
|
|
1299
|
+
}
|
|
1300
|
+
return host;
|
|
1301
|
+
}
|
|
1302
|
+
function resolveKeyboardTouchTargetFromPoint(doc, clientX, clientY) {
|
|
1303
|
+
const exactTarget = doc.elementFromPoint(clientX, clientY);
|
|
1304
|
+
const exactKeyboardTarget = resolveKeyboardInputTarget(exactTarget);
|
|
1305
|
+
if (exactKeyboardTarget) {
|
|
1306
|
+
return {
|
|
1307
|
+
focusTarget: exactKeyboardTarget,
|
|
1308
|
+
clickTarget: isHTMLElement(exactTarget) ? exactTarget : exactKeyboardTarget
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
if (isInteractiveElement(exactTarget) || exactTarget?.closest('label') != null) {
|
|
1312
|
+
return KEYBOARD_TAP_BLOCKED;
|
|
1313
|
+
}
|
|
1314
|
+
for (const [offsetX, offsetY] of [
|
|
1315
|
+
[0, INPUT_TAP_HIT_SLOP],
|
|
1316
|
+
[0, -INPUT_TAP_HIT_SLOP],
|
|
1317
|
+
[INPUT_TAP_HIT_SLOP, 0],
|
|
1318
|
+
[-INPUT_TAP_HIT_SLOP, 0]
|
|
1319
|
+
]) {
|
|
1320
|
+
const keyboardTarget = resolveKeyboardInputTarget(doc.elementFromPoint(clientX + offsetX, clientY + offsetY));
|
|
1321
|
+
if (keyboardTarget) {
|
|
1322
|
+
return {
|
|
1323
|
+
focusTarget: keyboardTarget,
|
|
1324
|
+
clickTarget: keyboardTarget
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
return null;
|
|
1329
|
+
}
|
|
1330
|
+
function isInteractiveElement(element) {
|
|
1331
|
+
if (!(element instanceof HTMLElement)) {
|
|
1332
|
+
return false;
|
|
1333
|
+
}
|
|
1334
|
+
return (element.isContentEditable ||
|
|
1335
|
+
element.matches('a[href],button,input,select,textarea,summary,[role="button"],[role="checkbox"],[role="radio"],[role="switch"],[tabindex]:not([tabindex="-1"])'));
|
|
1336
|
+
}
|
|
1337
|
+
function dispatchKeyboardClick(target, touch) {
|
|
1338
|
+
const win = target.ownerDocument.defaultView;
|
|
1339
|
+
if (!win) {
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
const ClickEvent = win.PointerEvent ?? win.MouseEvent;
|
|
1343
|
+
target.dispatchEvent(new ClickEvent('click', {
|
|
1344
|
+
bubbles: true,
|
|
1345
|
+
cancelable: true,
|
|
1346
|
+
clientX: touch.clientX,
|
|
1347
|
+
clientY: touch.clientY,
|
|
1348
|
+
detail: 1,
|
|
1349
|
+
view: win
|
|
1350
|
+
}));
|
|
1351
|
+
}
|
|
1352
|
+
function focusKeyboardInputWithoutPageScroll(target) {
|
|
1353
|
+
const wasFocused = target.ownerDocument.activeElement === target;
|
|
1354
|
+
const previousOpacity = target.style.opacity;
|
|
1355
|
+
const previousTransform = target.style.transform;
|
|
1356
|
+
const previousTransition = target.style.transition;
|
|
1357
|
+
target.style.transition = 'none';
|
|
1358
|
+
target.style.opacity = '0';
|
|
1359
|
+
target.style.transform = 'translateY(-2000px)';
|
|
1360
|
+
try {
|
|
1361
|
+
if (wasFocused) {
|
|
1362
|
+
target.blur();
|
|
1363
|
+
}
|
|
1364
|
+
target.focus({ preventScroll: true });
|
|
1365
|
+
}
|
|
1366
|
+
finally {
|
|
1367
|
+
target.style.opacity = previousOpacity;
|
|
1368
|
+
target.style.transform = previousTransform;
|
|
1369
|
+
target.style.transition = previousTransition;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
function findKeyboardScrollTarget(target, root) {
|
|
1373
|
+
let node = target.parentNode;
|
|
1374
|
+
while (node) {
|
|
1375
|
+
if (node instanceof HTMLElement && isKeyboardScrollable(node)) {
|
|
1376
|
+
return node;
|
|
1377
|
+
}
|
|
1378
|
+
if (node === root) {
|
|
1379
|
+
break;
|
|
1380
|
+
}
|
|
1381
|
+
node = node.parentNode;
|
|
1382
|
+
}
|
|
1383
|
+
return null;
|
|
1384
|
+
}
|
|
1385
|
+
function isKeyboardScrollable(element) {
|
|
1386
|
+
const overflowY = getComputedStyle(element).overflowY;
|
|
1387
|
+
return (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay') && element.scrollHeight > 0;
|
|
1388
|
+
}
|
|
1389
|
+
function getKeyboardVisualViewport(win) {
|
|
1390
|
+
const visualViewport = win.visualViewport;
|
|
1391
|
+
if (!visualViewport || visualViewport.scale !== 1) {
|
|
1392
|
+
return null;
|
|
1393
|
+
}
|
|
1394
|
+
const reducedHeight = win.innerHeight - visualViewport.height;
|
|
1395
|
+
if (reducedHeight <= KEYBOARD_RESIZE_THRESHOLD) {
|
|
1396
|
+
return null;
|
|
1397
|
+
}
|
|
1398
|
+
const top = Math.max(0, visualViewport.offsetTop);
|
|
1399
|
+
return {
|
|
1400
|
+
top,
|
|
1401
|
+
bottom: Math.min(win.innerHeight, top + visualViewport.height)
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
function getDrawerKeyboardInset(win, keyboardViewport) {
|
|
1405
|
+
return Math.max(0, win.innerHeight - keyboardViewport.bottom);
|
|
1406
|
+
}
|
|
1407
|
+
function isKeyboardVisualViewportOpen(win) {
|
|
1408
|
+
return !win.visualViewport || getKeyboardVisualViewport(win) !== null;
|
|
1409
|
+
}
|
|
1410
|
+
function prefersReducedMotion(win) {
|
|
1411
|
+
return !!win.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
977
1414
|
/**
|
|
978
1415
|
* Connects a drawer root with trigger elements rendered elsewhere in the DOM.
|
|
979
1416
|
*
|
|
@@ -993,6 +1430,7 @@ const drawerImports = [
|
|
|
993
1430
|
RdxDrawerPortalMisuseGuard,
|
|
994
1431
|
RdxDrawerBackdrop,
|
|
995
1432
|
RdxDrawerViewport,
|
|
1433
|
+
RdxDrawerVirtualKeyboardProvider,
|
|
996
1434
|
RdxDrawerPopup,
|
|
997
1435
|
RdxDrawerContent,
|
|
998
1436
|
RdxDrawerTitle,
|
|
@@ -1011,6 +1449,7 @@ class RdxDrawerModule {
|
|
|
1011
1449
|
RdxDrawerPortalMisuseGuard,
|
|
1012
1450
|
RdxDrawerBackdrop,
|
|
1013
1451
|
RdxDrawerViewport,
|
|
1452
|
+
RdxDrawerVirtualKeyboardProvider,
|
|
1014
1453
|
RdxDrawerPopup,
|
|
1015
1454
|
RdxDrawerContent,
|
|
1016
1455
|
RdxDrawerTitle,
|
|
@@ -1025,6 +1464,7 @@ class RdxDrawerModule {
|
|
|
1025
1464
|
RdxDrawerPortalMisuseGuard,
|
|
1026
1465
|
RdxDrawerBackdrop,
|
|
1027
1466
|
RdxDrawerViewport,
|
|
1467
|
+
RdxDrawerVirtualKeyboardProvider,
|
|
1028
1468
|
RdxDrawerPopup,
|
|
1029
1469
|
RdxDrawerContent,
|
|
1030
1470
|
RdxDrawerTitle,
|
|
@@ -1046,5 +1486,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1046
1486
|
* Generated bundle index. Do not edit.
|
|
1047
1487
|
*/
|
|
1048
1488
|
|
|
1049
|
-
export { RdxDrawerBackdrop, RdxDrawerClose, RdxDrawerContent, RdxDrawerDescription, RdxDrawerHandle, RdxDrawerIndent, RdxDrawerIndentBackground, RdxDrawerModule, RdxDrawerPopup, RdxDrawerPortal, RdxDrawerPortalMisuseGuard, RdxDrawerProvider, RdxDrawerProviderDirective, RdxDrawerRoot, RdxDrawerSwipeArea, RdxDrawerTitle, RdxDrawerTrigger, RdxDrawerViewport, buildSnapEntries, createRdxDrawerHandle, dismissUnitVector, drawerImports, injectRdxDrawerRootContext, provideRdxDrawerProvider, provideRdxDrawerRootContext, resolveSnapTarget, snapPointReveal, useDrawerSwipe };
|
|
1489
|
+
export { RdxDrawerBackdrop, RdxDrawerClose, RdxDrawerContent, RdxDrawerDescription, RdxDrawerHandle, RdxDrawerIndent, RdxDrawerIndentBackground, RdxDrawerModule, RdxDrawerPopup, RdxDrawerPortal, RdxDrawerPortalMisuseGuard, RdxDrawerProvider, RdxDrawerProviderDirective, RdxDrawerRoot, RdxDrawerSwipeArea, RdxDrawerTitle, RdxDrawerTrigger, RdxDrawerViewport, RdxDrawerVirtualKeyboardProvider, buildSnapEntries, createRdxDrawerHandle, dismissUnitVector, drawerImports, injectRdxDrawerRootContext, provideRdxDrawerProvider, provideRdxDrawerRootContext, resolveSnapTarget, snapPointReveal, useDrawerSwipe };
|
|
1050
1490
|
//# sourceMappingURL=radix-ng-primitives-drawer.mjs.map
|