@astryxdesign/core 0.7.9-canary.dedecd0 → 0.7.9-canary.df15de7
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/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +3 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +3 -1
- package/dist/Layer/LayerTouch.d.ts +13 -0
- package/dist/Layer/LayerTouch.d.ts.map +1 -0
- package/dist/Layer/LayerTouch.js +16 -0
- package/dist/Layer/layerKeyboardClearance.d.ts +41 -0
- package/dist/Layer/layerKeyboardClearance.d.ts.map +1 -0
- package/dist/Layer/layerKeyboardClearance.js +51 -0
- package/dist/Layer/layerViewportInset.stylex.d.ts +5 -1
- package/dist/Layer/layerViewportInset.stylex.d.ts.map +1 -1
- package/dist/Layer/layerViewportInset.stylex.js +11 -4
- package/dist/Layer/settledBox.d.ts +16 -0
- package/dist/Layer/settledBox.d.ts.map +1 -0
- package/dist/Layer/settledBox.js +117 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +36 -106
- package/dist/Layer/useLayerKeyboardClearance.d.ts +54 -0
- package/dist/Layer/useLayerKeyboardClearance.d.ts.map +1 -0
- package/dist/Layer/useLayerKeyboardClearance.js +330 -0
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +7 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +1 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +17 -12
- package/dist/Switch/useSwitchTouch.d.ts.map +1 -1
- package/dist/Switch/useSwitchTouch.js +9 -5
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +1 -1
- package/dist/astryx.css +8 -3
- package/dist/motion/animatedLayout.d.ts.map +1 -1
- package/dist/motion/animatedLayout.js +10 -7
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +3 -2
- package/dist/motion/resolveMotion.d.ts +6 -27
- package/dist/motion/resolveMotion.d.ts.map +1 -1
- package/dist/motion/resolveMotion.js +82 -16
- package/dist/motion/themeTempo.d.ts +7 -0
- package/dist/motion/themeTempo.d.ts.map +1 -0
- package/dist/motion/themeTempo.js +38 -0
- package/dist/theme/defineTheme.d.ts +2 -2
- package/dist/theme/resolveThemeValues.d.ts.map +1 -1
- package/dist/theme/resolveThemeValues.js +12 -4
- package/dist/theme/themeMotion.d.ts +7 -5
- package/dist/theme/themeMotion.d.ts.map +1 -1
- package/dist/theme/themeMotion.js +7 -5
- package/package.json +4 -4
- package/src/Breadcrumbs/BreadcrumbItem.tsx +7 -1
- package/src/ContextMenu/ContextMenu.tsx +7 -1
- package/src/Layer/LayerTouch.ts +17 -0
- package/src/Layer/layerKeyboardClearance.ts +55 -0
- package/src/Layer/layerViewportInset.stylex.ts +16 -5
- package/src/Layer/settledBox.ts +138 -0
- package/src/Layer/useLayer.tsx +41 -123
- package/src/Layer/useLayerKeyboardClearance.ts +371 -0
- package/src/MultiSelector/MultiSelector.tsx +24 -2
- package/src/Popover/Popover.tsx +5 -0
- package/src/Selector/Selector.tsx +24 -2
- package/src/Switch/useSwitchTouch.ts +13 -5
- package/src/Typeahead/BaseTypeahead.tsx +7 -2
- package/src/gestures/createPanGesture.doc.mjs +1 -1
- package/src/hooks/usePanGesture.doc.mjs +2 -3
- package/src/motion/README.md +3 -2
- package/src/motion/animatedLayout.ts +10 -7
- package/src/motion/animator.ts +3 -2
- package/src/motion/resolveMotion.ts +89 -18
- package/src/motion/themeTempo.ts +41 -0
- package/src/theme/defineTheme.ts +2 -2
- package/src/theme/resolveThemeValues.ts +12 -3
- package/src/theme/themeMotion.ts +7 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BreadcrumbItem.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/BreadcrumbItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"BreadcrumbItem.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/BreadcrumbItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAc5C,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,qCAAqC,CAAC;AAM7C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAarE,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,SAAS,CAAC,aAAa,CAAC,EACxB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/C;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AA2ID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EACH,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,SAAS,EAAE,aAAa,EACxB,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,mBAAmB,qBAuMrB;yBAtNe,cAAc"}
|
|
@@ -41,6 +41,8 @@ import { menuTouchActionStyles } from "../DropdownMenu/menuTouchAction.stylex.js
|
|
|
41
41
|
import { useMenuOverflow } from "../DropdownMenu/useMenuOverflow.js";
|
|
42
42
|
import { useTypeahead } from "../hooks/useTypeahead.js";
|
|
43
43
|
import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
|
|
44
|
+
import "../Layer/layerViewportInset.stylex.js";
|
|
45
|
+
import { layerViewportInset } from "../Layer/layerViewportInset.stylex.js";
|
|
44
46
|
import { renderDropdownItems } from "../DropdownMenu/renderDropdownItems.js";
|
|
45
47
|
import { DropdownMenuContext, DropdownMenuRootOpenContext } from "../DropdownMenu/DropdownMenuContext.js";
|
|
46
48
|
import { MENU_ITEM_ROLES, MENU_ITEM_SELECTOR, MENU_BOUNDARY_SELECTOR } from "../DropdownMenu/menuItemRoles.js";
|
|
@@ -131,7 +133,7 @@ const menuStyles = {
|
|
|
131
133
|
k1xSpc: "x78zum5",
|
|
132
134
|
kXwgrk: "xdt5ytf",
|
|
133
135
|
kOIVth: "x1lsbc85",
|
|
134
|
-
kskxy: "
|
|
136
|
+
kskxy: "x1uh1i8a",
|
|
135
137
|
kORKVm: "x1odjw0f",
|
|
136
138
|
"--_dropdown-menu-radius": "x1fcsqxe",
|
|
137
139
|
"--_dropdown-menu-padding": "xgory14",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../src/ContextMenu/ContextMenu.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KASN,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../src/ContextMenu/ContextMenu.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KASN,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAyCrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACpB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAC;AAqI1C,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AAEvD,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAMnD,UAAU,oBAAqB,SAAQ,SAAS;IAC9C,oDAAoD;IACpD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IAC9C,+DAA+D;IAC/D,QAAQ,EAAE,SAAS,CAAC;IACpB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,wCAAwC;IACxC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,oBAAqB,SAAQ,oBAAoB;IACzD,gDAAgD;IAChD,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,UAAU,wBAAyB,SAAQ,oBAAoB;IAC7D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,+CAA+C;IAC/C,WAAW,EAAE,SAAS,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG,wBAAwB,CAAC;AAM/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,SAAS,EACT,IAAW,EACX,KAAK,EAAE,cAAc,EACrB,UAAkB,EAClB,YAAY,EACZ,YAAwB,EACxB,SAAiB,EACjB,GAAG,EACH,SAAS,EACT,KAAK,EACL,MAAM,EACN,aAAa,EACb,aAAa,EAAE,iBAAiB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,WAAW,EAAE,eAAe,EAC5B,UAAU,EAAE,cAAc,EAC1B,aAAa,EAAE,iBAAiB,EAChC,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,gBAAgB,qBAijBlB;yBAtkBe,WAAW"}
|
|
@@ -61,6 +61,8 @@ import { useMenuPress } from "../hooks/useMenuPress.js";
|
|
|
61
61
|
import { useTypeahead } from "../hooks/useTypeahead.js";
|
|
62
62
|
import { useLongPress } from "../hooks/useLongPress.js";
|
|
63
63
|
import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
|
|
64
|
+
import "../Layer/layerViewportInset.stylex.js";
|
|
65
|
+
import { layerViewportInset } from "../Layer/layerViewportInset.stylex.js";
|
|
64
66
|
import "../theme/tokens.stylex.js";
|
|
65
67
|
import { colorVars, spacingVars, radiusVars, durationVars, easeVars, shadowVars } from "../theme/tokens.stylex.js";
|
|
66
68
|
import { mergeProps, rtlStyles } from "../utils/index.js";
|
|
@@ -87,7 +89,7 @@ const styles = {
|
|
|
87
89
|
k1xSpc: "x78zum5",
|
|
88
90
|
kXwgrk: "xdt5ytf",
|
|
89
91
|
kOIVth: "x1lsbc85",
|
|
90
|
-
kskxy: "
|
|
92
|
+
kskxy: "x1uh1i8a",
|
|
91
93
|
kORKVm: "x1odjw0f",
|
|
92
94
|
"--_dropdown-menu-radius": "x1fcsqxe",
|
|
93
95
|
"--_dropdown-menu-padding": "xgory14",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file LayerTouch.ts
|
|
3
|
+
* @input useLayerKeyboardClearance.ts (the software keyboard's part of the
|
|
4
|
+
* viewport caps)
|
|
5
|
+
* @output The layer runtime's touch layer: useLayerKeyboardClearance
|
|
6
|
+
* @position The one module the layer runtime imports touch-only code through,
|
|
7
|
+
* and its only import site is useLayer.tsx. It is imported statically, as
|
|
8
|
+
* every touch module is.
|
|
9
|
+
*
|
|
10
|
+
* SYNC: When modified, keep every touch-only import of useLayer.tsx here.
|
|
11
|
+
*/
|
|
12
|
+
export { useLayerKeyboardClearance } from './useLayerKeyboardClearance.js';
|
|
13
|
+
//# sourceMappingURL=LayerTouch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayerTouch.d.ts","sourceRoot":"","sources":["../../src/Layer/LayerTouch.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAC,yBAAyB,EAAC,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file LayerTouch.ts
|
|
7
|
+
* @input useLayerKeyboardClearance.ts (the software keyboard's part of the
|
|
8
|
+
* viewport caps)
|
|
9
|
+
* @output The layer runtime's touch layer: useLayerKeyboardClearance
|
|
10
|
+
* @position The one module the layer runtime imports touch-only code through,
|
|
11
|
+
* and its only import site is useLayer.tsx. It is imported statically, as
|
|
12
|
+
* every touch module is.
|
|
13
|
+
*
|
|
14
|
+
* SYNC: When modified, keep every touch-only import of useLayer.tsx here.
|
|
15
|
+
*/
|
|
16
|
+
export { useLayerKeyboardClearance } from "./useLayerKeyboardClearance.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file layerKeyboardClearance.ts
|
|
3
|
+
* @input A layer's box, the layout viewport's height and the keyboard's
|
|
4
|
+
* cover
|
|
5
|
+
* @output Exports `LAYER_KEYBOARD_CLEARANCE_PX`, `LAYER_ANCHORED_ATTRIBUTE` and
|
|
6
|
+
* `keyboardClearanceCap`
|
|
7
|
+
* @position Layer runtime: the software keyboard cap's numbers, with no DOM
|
|
8
|
+
* and no React. A browser proof can import them on its own.
|
|
9
|
+
* useLayerKeyboardClearance.ts applies them.
|
|
10
|
+
*
|
|
11
|
+
* SYNC: When modified, update:
|
|
12
|
+
* - /packages/core/src/Layer/useLayerKeyboardClearance.ts
|
|
13
|
+
* - /packages/core/src/Layer/useLayerKeyboardClearance.test.tsx
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* How far above the software keyboard a capped layer ends, CSS px. It is the
|
|
17
|
+
* clearance UIKit keeps under a popover the keyboard would cover.
|
|
18
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. A
|
|
19
|
+
* 320 × 533 popover below a source at y 160 (top 204) shrank to 325 pt.
|
|
20
|
+
* Its bottom stopped at 529, with the keyboard's top at about 539. It
|
|
21
|
+
* shrank from UIKeyboardWillShow over the keyboard's 0.3833 s, and grew
|
|
22
|
+
* back the same way on the hide. A 320 × 240 popover clear of the keyboard
|
|
23
|
+
* did not move.
|
|
24
|
+
*/
|
|
25
|
+
export declare const LAYER_KEYBOARD_CLEARANCE_PX = 10;
|
|
26
|
+
/**
|
|
27
|
+
* The attribute useLayer.tsx renders on a layer in anchor positioning. The
|
|
28
|
+
* cap reads it from the committed element at measurement, not from a value a
|
|
29
|
+
* render wrote. Only an anchored layer is capped.
|
|
30
|
+
*/
|
|
31
|
+
export declare const LAYER_ANCHORED_ATTRIBUTE = "data-layer-anchored";
|
|
32
|
+
/**
|
|
33
|
+
* The block size that keeps a layer `LAYER_KEYBOARD_CLEARANCE_PX` above a
|
|
34
|
+
* keyboard covering `inset` px of the layout viewport's bottom. It is null
|
|
35
|
+
* when the layer, at its own size, is already clear of the keyboard.
|
|
36
|
+
*/
|
|
37
|
+
export declare function keyboardClearanceCap(box: {
|
|
38
|
+
top: number;
|
|
39
|
+
bottom: number;
|
|
40
|
+
}, viewportHeight: number, inset: number): number | null;
|
|
41
|
+
//# sourceMappingURL=layerKeyboardClearance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layerKeyboardClearance.d.ts","sourceRoot":"","sources":["../../src/Layer/layerKeyboardClearance.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,EAClC,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CASf"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file layerKeyboardClearance.ts
|
|
5
|
+
* @input A layer's box, the layout viewport's height and the keyboard's
|
|
6
|
+
* cover
|
|
7
|
+
* @output Exports `LAYER_KEYBOARD_CLEARANCE_PX`, `LAYER_ANCHORED_ATTRIBUTE` and
|
|
8
|
+
* `keyboardClearanceCap`
|
|
9
|
+
* @position Layer runtime: the software keyboard cap's numbers, with no DOM
|
|
10
|
+
* and no React. A browser proof can import them on its own.
|
|
11
|
+
* useLayerKeyboardClearance.ts applies them.
|
|
12
|
+
*
|
|
13
|
+
* SYNC: When modified, update:
|
|
14
|
+
* - /packages/core/src/Layer/useLayerKeyboardClearance.ts
|
|
15
|
+
* - /packages/core/src/Layer/useLayerKeyboardClearance.test.tsx
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* How far above the software keyboard a capped layer ends, CSS px. It is the
|
|
20
|
+
* clearance UIKit keeps under a popover the keyboard would cover.
|
|
21
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. A
|
|
22
|
+
* 320 × 533 popover below a source at y 160 (top 204) shrank to 325 pt.
|
|
23
|
+
* Its bottom stopped at 529, with the keyboard's top at about 539. It
|
|
24
|
+
* shrank from UIKeyboardWillShow over the keyboard's 0.3833 s, and grew
|
|
25
|
+
* back the same way on the hide. A 320 × 240 popover clear of the keyboard
|
|
26
|
+
* did not move.
|
|
27
|
+
*/
|
|
28
|
+
export const LAYER_KEYBOARD_CLEARANCE_PX = 10;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The attribute useLayer.tsx renders on a layer in anchor positioning. The
|
|
32
|
+
* cap reads it from the committed element at measurement, not from a value a
|
|
33
|
+
* render wrote. Only an anchored layer is capped.
|
|
34
|
+
*/
|
|
35
|
+
export const LAYER_ANCHORED_ATTRIBUTE = 'data-layer-anchored';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The block size that keeps a layer `LAYER_KEYBOARD_CLEARANCE_PX` above a
|
|
39
|
+
* keyboard covering `inset` px of the layout viewport's bottom. It is null
|
|
40
|
+
* when the layer, at its own size, is already clear of the keyboard.
|
|
41
|
+
*/
|
|
42
|
+
export function keyboardClearanceCap(box, viewportHeight, inset) {
|
|
43
|
+
if (inset <= 0) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const limit = viewportHeight - inset - LAYER_KEYBOARD_CLEARANCE_PX;
|
|
47
|
+
if (box.bottom <= limit) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return Math.max(0, limit - box.top);
|
|
51
|
+
}
|
|
@@ -23,7 +23,11 @@ export declare const layerViewportInset: {
|
|
|
23
23
|
/** The largest inline size a layer may take: the viewport minus both gutters. */
|
|
24
24
|
maxInlineSize: string;
|
|
25
25
|
maxInlineSizeFallback: string;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* The largest block size a layer may take: the viewport minus both
|
|
28
|
+
* gutters. It is no more than the room the software keyboard leaves while
|
|
29
|
+
* it caps the layer.
|
|
30
|
+
*/
|
|
27
31
|
maxBlockSize: string;
|
|
28
32
|
maxBlockSizeFallback: string;
|
|
29
33
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layerViewportInset.stylex.d.ts","sourceRoot":"","sources":["../../src/Layer/layerViewportInset.stylex.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"layerViewportInset.stylex.d.ts","sourceRoot":"","sources":["../../src/Layer/layerViewportInset.stylex.ts"],"names":[],"mappings":"AA+DA;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;IAC7B,iDAAiD;;IAEjD,+CAA+C;;IAE/C,+CAA+C;;IAE/C,gFAAgF;;;;;;IAMhF,iFAAiF;;;IAGjF;;;;OAIG;;;CAGH,CAAC"}
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file layerViewportInset.stylex.ts
|
|
5
|
-
* @input Uses the spacing token, the device safe-area insets,
|
|
6
|
-
* app-declared `--astryx-layer-inset-*` custom properties
|
|
5
|
+
* @input Uses the spacing token, the device safe-area insets, the
|
|
6
|
+
* app-declared `--astryx-layer-inset-*` custom properties, and the
|
|
7
|
+
* keyboard cap each layer's own style declares
|
|
8
|
+
* (`--_layer-keyboard-max-block-size`)
|
|
7
9
|
* @output Exports the one definition of an anchored layer's viewport gutter
|
|
8
10
|
* and the size caps derived from it
|
|
9
11
|
* @position Layer runtime geometry; read by useLayer and by consumers that
|
|
@@ -27,6 +29,7 @@
|
|
|
27
29
|
*
|
|
28
30
|
* SYNC: When modified, update these files to stay in sync:
|
|
29
31
|
* - /packages/core/src/Layer/useLayer.tsx
|
|
32
|
+
* - /packages/core/src/Layer/useLayerKeyboardClearance.ts
|
|
30
33
|
* - /packages/core/src/Layer/layerViewportInset.test.ts
|
|
31
34
|
* - /docs/specs/AST-059-layer-viewport-inset/spec.md
|
|
32
35
|
*/
|
|
@@ -41,6 +44,10 @@ const INSET_BLOCK_START = 'var(--astryx-layer-inset-block-start, 0px)';
|
|
|
41
44
|
const INSET_BLOCK_END = 'var(--astryx-layer-inset-block-end, 0px)';
|
|
42
45
|
const INSET_INLINE_START = 'var(--astryx-layer-inset-inline-start, 0px)';
|
|
43
46
|
const INSET_INLINE_END = 'var(--astryx-layer-inset-inline-end, 0px)';
|
|
47
|
+
// Each layer's own style declares the room the software keyboard leaves it
|
|
48
|
+
// (useLayer.tsx's `keyboardCap`, from useLayerKeyboardClearance.ts). An
|
|
49
|
+
// uncapped layer declares a limit out of reach.
|
|
50
|
+
const KEYBOARD_CAP_PROPERTY = '--_layer-keyboard-max-block-size';
|
|
44
51
|
const GUTTER_BLOCK_START = `calc(max(${SPACING}, env(safe-area-inset-top, 0px)) + ${INSET_BLOCK_START})`;
|
|
45
52
|
const GUTTER_BLOCK_END = `calc(max(${SPACING}, env(safe-area-inset-bottom, 0px)) + ${INSET_BLOCK_END})`;
|
|
46
53
|
const GUTTER_INLINE_LEFT = `calc(max(${SPACING}, env(safe-area-inset-left, 0px)) + ${INSET_INLINE_START})`;
|
|
@@ -72,6 +79,6 @@ export const layerViewportInset = {
|
|
|
72
79
|
gutterInlineFallback: "calc(var(--spacing-4) + max(var(--astryx-layer-inset-inline-start, 0px), var(--astryx-layer-inset-inline-end, 0px)))",
|
|
73
80
|
maxInlineSize: "calc(100vi - calc(max(var(--spacing-4), env(safe-area-inset-left, 0px)) + var(--astryx-layer-inset-inline-start, 0px)) - calc(max(var(--spacing-4), env(safe-area-inset-right, 0px)) + var(--astryx-layer-inset-inline-end, 0px)))",
|
|
74
81
|
maxInlineSizeFallback: "calc(100vw - var(--spacing-4) - var(--spacing-4) - var(--astryx-layer-inset-inline-start, 0px) - var(--astryx-layer-inset-inline-end, 0px))",
|
|
75
|
-
maxBlockSize: "calc(100dvb - calc(max(var(--spacing-4), env(safe-area-inset-top, 0px)) + var(--astryx-layer-inset-block-start, 0px)) - calc(max(var(--spacing-4), env(safe-area-inset-bottom, 0px)) + var(--astryx-layer-inset-block-end, 0px)))",
|
|
76
|
-
maxBlockSizeFallback: "calc(100vh - var(--spacing-4) - var(--spacing-4) - var(--astryx-layer-inset-block-start, 0px) - var(--astryx-layer-inset-block-end, 0px))"
|
|
82
|
+
maxBlockSize: "min(calc(100dvb - calc(max(var(--spacing-4), env(safe-area-inset-top, 0px)) + var(--astryx-layer-inset-block-start, 0px)) - calc(max(var(--spacing-4), env(safe-area-inset-bottom, 0px)) + var(--astryx-layer-inset-block-end, 0px))), var(--_layer-keyboard-max-block-size, 100dvb))",
|
|
83
|
+
maxBlockSizeFallback: "min(calc(100vh - var(--spacing-4) - var(--spacing-4) - var(--astryx-layer-inset-block-start, 0px) - var(--astryx-layer-inset-block-end, 0px)), var(--_layer-keyboard-max-block-size, 100vh))"
|
|
77
84
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layer's box where its position option put it, without the transform an
|
|
3
|
+
* entry animation (or anything else) applies to it. A Tooltip enters from a
|
|
4
|
+
* few pixels toward its trigger, scaled down. So the transformed box of a
|
|
5
|
+
* tooltip that fits beside its trigger can read as covering it while it
|
|
6
|
+
* enters. For this one read, the layer's transforms are overridden with
|
|
7
|
+
* `none !important`, which outranks an animation. They are restored in the
|
|
8
|
+
* same task, so no frame paints in between and the animation keeps running.
|
|
9
|
+
* Where the engine still applies an animated transform under that override
|
|
10
|
+
* (WebKit), the read box has that transform undone instead (`untransform`). A
|
|
11
|
+
* layer that transitions a transform property is not overridden, since
|
|
12
|
+
* restoring the value would start that transition. Its box has its transform
|
|
13
|
+
* undone.
|
|
14
|
+
*/
|
|
15
|
+
export declare function settledBox(layer: HTMLElement): DOMRect;
|
|
16
|
+
//# sourceMappingURL=settledBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settledBox.d.ts","sourceRoot":"","sources":["../../src/Layer/settledBox.ts"],"names":[],"mappings":"AAoFA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAuCtD"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file settledBox.ts
|
|
5
|
+
* @input A layer element
|
|
6
|
+
* @output Exports `settledBox`: the layer's box where its position option put
|
|
7
|
+
* it, without the transform an entrance (or anything else) applies to it
|
|
8
|
+
* @position Layer runtime: the one box read the fallback order and the
|
|
9
|
+
* software keyboard's cap both measure with (useLayer.tsx,
|
|
10
|
+
* useLayerKeyboardClearance.ts)
|
|
11
|
+
*
|
|
12
|
+
* SYNC: When modified, update:
|
|
13
|
+
* - /packages/core/src/Layer/useLayer.tsx
|
|
14
|
+
* - /packages/core/src/Layer/useLayerKeyboardClearance.ts
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const TRANSFORM_PROPERTIES = ['transform', 'translate', 'scale', 'rotate'];
|
|
18
|
+
function hasTransform(style) {
|
|
19
|
+
return TRANSFORM_PROPERTIES.some(name => {
|
|
20
|
+
const value = style.getPropertyValue(name);
|
|
21
|
+
return value !== '' && value !== 'none';
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `rect`, the box of an element whose computed style still carries a 2D
|
|
27
|
+
* transform, with that transform undone. The transformed box's centre is the
|
|
28
|
+
* image of the element's centre. So undoing the transform about its origin on
|
|
29
|
+
* that centre gives the untransformed box, at the element's layout size. A
|
|
30
|
+
* transform this cannot undo (3D, or a rotation in another unit) leaves `rect`
|
|
31
|
+
* as it is.
|
|
32
|
+
*/
|
|
33
|
+
function untransform(rect, layer, style) {
|
|
34
|
+
const set = value => value !== '' && value !== 'none';
|
|
35
|
+
if (typeof DOMMatrix === 'undefined' || layer.offsetWidth <= 0) {
|
|
36
|
+
return rect;
|
|
37
|
+
}
|
|
38
|
+
// The individual transform properties apply before `transform`, in this
|
|
39
|
+
// order (CSS Transforms 2).
|
|
40
|
+
let matrix = new DOMMatrix();
|
|
41
|
+
if (set(style.translate)) {
|
|
42
|
+
const [x = '0', y = '0', z] = style.translate.split(' ');
|
|
43
|
+
if (z != null) {
|
|
44
|
+
return rect;
|
|
45
|
+
}
|
|
46
|
+
matrix = matrix.translate(parseFloat(x), parseFloat(y));
|
|
47
|
+
}
|
|
48
|
+
if (set(style.rotate)) {
|
|
49
|
+
if (!/^-?[\d.]+deg$/.test(style.rotate)) {
|
|
50
|
+
return rect;
|
|
51
|
+
}
|
|
52
|
+
matrix = matrix.rotate(parseFloat(style.rotate));
|
|
53
|
+
}
|
|
54
|
+
if (set(style.scale)) {
|
|
55
|
+
const [x = '1', y = x, z] = style.scale.split(' ');
|
|
56
|
+
if (z != null) {
|
|
57
|
+
return rect;
|
|
58
|
+
}
|
|
59
|
+
matrix = matrix.scale(parseFloat(x), parseFloat(y));
|
|
60
|
+
}
|
|
61
|
+
if (set(style.transform)) {
|
|
62
|
+
matrix = matrix.multiply(new DOMMatrix(style.transform));
|
|
63
|
+
}
|
|
64
|
+
if (!matrix.is2D) {
|
|
65
|
+
return rect;
|
|
66
|
+
}
|
|
67
|
+
const [originX = 0, originY = 0] = style.transformOrigin.split(' ').map(value => parseFloat(value));
|
|
68
|
+
const width = layer.offsetWidth;
|
|
69
|
+
const height = layer.offsetHeight;
|
|
70
|
+
const centre = matrix.transformPoint(new DOMPoint(width / 2 - originX, height / 2 - originY));
|
|
71
|
+
const left = rect.left + rect.width / 2 - centre.x - originX;
|
|
72
|
+
const top = rect.top + rect.height / 2 - centre.y - originY;
|
|
73
|
+
return new DOMRect(left, top, width, height);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The layer's box where its position option put it, without the transform an
|
|
78
|
+
* entry animation (or anything else) applies to it. A Tooltip enters from a
|
|
79
|
+
* few pixels toward its trigger, scaled down. So the transformed box of a
|
|
80
|
+
* tooltip that fits beside its trigger can read as covering it while it
|
|
81
|
+
* enters. For this one read, the layer's transforms are overridden with
|
|
82
|
+
* `none !important`, which outranks an animation. They are restored in the
|
|
83
|
+
* same task, so no frame paints in between and the animation keeps running.
|
|
84
|
+
* Where the engine still applies an animated transform under that override
|
|
85
|
+
* (WebKit), the read box has that transform undone instead (`untransform`). A
|
|
86
|
+
* layer that transitions a transform property is not overridden, since
|
|
87
|
+
* restoring the value would start that transition. Its box has its transform
|
|
88
|
+
* undone.
|
|
89
|
+
*/
|
|
90
|
+
export function settledBox(layer) {
|
|
91
|
+
const view = layer.ownerDocument.defaultView;
|
|
92
|
+
const style = view?.getComputedStyle(layer);
|
|
93
|
+
if (style == null || !hasTransform(style)) {
|
|
94
|
+
return layer.getBoundingClientRect();
|
|
95
|
+
}
|
|
96
|
+
const transitions = style.transitionProperty.split(',').map(p => p.trim());
|
|
97
|
+
const durations = style.transitionDuration.split(',').map(parseFloat);
|
|
98
|
+
const transitioned = transitions.some((name, index) => (name === 'all' || TRANSFORM_PROPERTIES.includes(name)) && (durations[index % durations.length] ?? 0) > 0);
|
|
99
|
+
if (transitioned) {
|
|
100
|
+
return untransform(layer.getBoundingClientRect(), layer, style);
|
|
101
|
+
}
|
|
102
|
+
const saved = TRANSFORM_PROPERTIES.map(name => [name, layer.style.getPropertyValue(name), layer.style.getPropertyPriority(name)]);
|
|
103
|
+
for (const name of TRANSFORM_PROPERTIES) {
|
|
104
|
+
layer.style.setProperty(name, 'none', 'important');
|
|
105
|
+
}
|
|
106
|
+
const box = layer.getBoundingClientRect();
|
|
107
|
+
const under = view?.getComputedStyle(layer);
|
|
108
|
+
const settled = under != null && hasTransform(under) ? untransform(box, layer, under) : box;
|
|
109
|
+
for (const [name, value, priority] of saved) {
|
|
110
|
+
if (value === '') {
|
|
111
|
+
layer.style.removeProperty(name);
|
|
112
|
+
} else {
|
|
113
|
+
layer.style.setProperty(name, value, priority);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return settled;
|
|
117
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAQZ,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"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"}
|
package/dist/Layer/useLayer.js
CHANGED
|
@@ -25,6 +25,9 @@ import { layerTextReset } from "./layerTextReset.stylex.js";
|
|
|
25
25
|
import { layerStructureReset } from "./layerStructureReset.stylex.js";
|
|
26
26
|
import "./layerViewportInset.stylex.js";
|
|
27
27
|
import { layerViewportInset } from "./layerViewportInset.stylex.js";
|
|
28
|
+
import { useLayerKeyboardClearance } from "./LayerTouch.js";
|
|
29
|
+
import { LAYER_ANCHORED_ATTRIBUTE } from "./layerKeyboardClearance.js";
|
|
30
|
+
import { settledBox } from "./settledBox.js";
|
|
28
31
|
import { layerInsetProperties } from "./layerInset.js";
|
|
29
32
|
import { LAYER_CLEARANCE_PROPERTY, LAYER_CLEARS_ANCHOR_ATTRIBUTE, LAYER_SCROLLS_ATTRIBUTE, LAYER_CLEAR_FALLBACKS_PROPERTY, LAYER_TRY_FALLBACKS_PROPERTY, ensureSlideRules, getAnchorClearFallbacks, slideRuleName } from "./layerSlideRules.js";
|
|
30
33
|
import { afterPopoverOperations, isBrowserHideInFlight, isPopoverOperationInFlight, observeBrowserHide, runPopoverOperation } from "./popoverOperations.js";
|
|
@@ -52,6 +55,14 @@ const _temp4 = {
|
|
|
52
55
|
"$$css": true
|
|
53
56
|
};
|
|
54
57
|
const styles = {
|
|
58
|
+
keyboardCap: (cap, overflow) => [{
|
|
59
|
+
"--_layer-keyboard-max-block-size": cap != null ? "x1ex41ac" : cap,
|
|
60
|
+
"--_layer-keyboard-overflow": overflow != null ? "xypflj0" : overflow,
|
|
61
|
+
$$css: true
|
|
62
|
+
}, {
|
|
63
|
+
"--x---_layer-keyboard-max-block-size": cap != null ? cap : undefined,
|
|
64
|
+
"--x---_layer-keyboard-overflow": overflow != null ? overflow : undefined
|
|
65
|
+
}],
|
|
55
66
|
base: {
|
|
56
67
|
keoZOQ: "xdj266r",
|
|
57
68
|
k1K539: "xat24cr",
|
|
@@ -197,64 +208,6 @@ function placeAfresh(layer) {
|
|
|
197
208
|
layer.style.display = display;
|
|
198
209
|
});
|
|
199
210
|
}
|
|
200
|
-
const TRANSFORM_PROPERTIES = ['transform', 'translate', 'scale', 'rotate'];
|
|
201
|
-
function hasTransform(style) {
|
|
202
|
-
return TRANSFORM_PROPERTIES.some(name => {
|
|
203
|
-
const value = style.getPropertyValue(name);
|
|
204
|
-
return value !== '' && value !== 'none';
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* `rect`, the box of an element whose computed style still carries a 2D
|
|
210
|
-
* transform, with that transform undone: the transformed box's centre is the
|
|
211
|
-
* image of the element's centre, so undoing the transform about its origin on
|
|
212
|
-
* that centre gives the untransformed box, at the element's layout size. A
|
|
213
|
-
* transform this cannot undo (3D, or a rotation in another unit) leaves `rect`
|
|
214
|
-
* as it is.
|
|
215
|
-
*/
|
|
216
|
-
function untransform(rect, layer, style) {
|
|
217
|
-
const set = value => value !== '' && value !== 'none';
|
|
218
|
-
if (typeof DOMMatrix === 'undefined' || layer.offsetWidth <= 0) {
|
|
219
|
-
return rect;
|
|
220
|
-
}
|
|
221
|
-
// The individual transform properties apply before `transform`, in this
|
|
222
|
-
// order (CSS Transforms 2).
|
|
223
|
-
let matrix = new DOMMatrix();
|
|
224
|
-
if (set(style.translate)) {
|
|
225
|
-
const [x = '0', y = '0', z] = style.translate.split(' ');
|
|
226
|
-
if (z != null) {
|
|
227
|
-
return rect;
|
|
228
|
-
}
|
|
229
|
-
matrix = matrix.translate(parseFloat(x), parseFloat(y));
|
|
230
|
-
}
|
|
231
|
-
if (set(style.rotate)) {
|
|
232
|
-
if (!/^-?[\d.]+deg$/.test(style.rotate)) {
|
|
233
|
-
return rect;
|
|
234
|
-
}
|
|
235
|
-
matrix = matrix.rotate(parseFloat(style.rotate));
|
|
236
|
-
}
|
|
237
|
-
if (set(style.scale)) {
|
|
238
|
-
const [x = '1', y = x, z] = style.scale.split(' ');
|
|
239
|
-
if (z != null) {
|
|
240
|
-
return rect;
|
|
241
|
-
}
|
|
242
|
-
matrix = matrix.scale(parseFloat(x), parseFloat(y));
|
|
243
|
-
}
|
|
244
|
-
if (set(style.transform)) {
|
|
245
|
-
matrix = matrix.multiply(new DOMMatrix(style.transform));
|
|
246
|
-
}
|
|
247
|
-
if (!matrix.is2D) {
|
|
248
|
-
return rect;
|
|
249
|
-
}
|
|
250
|
-
const [originX = 0, originY = 0] = style.transformOrigin.split(' ').map(value => parseFloat(value));
|
|
251
|
-
const width = layer.offsetWidth;
|
|
252
|
-
const height = layer.offsetHeight;
|
|
253
|
-
const centre = matrix.transformPoint(new DOMPoint(width / 2 - originX, height / 2 - originY));
|
|
254
|
-
const left = rect.left + rect.width / 2 - centre.x - originX;
|
|
255
|
-
const top = rect.top + rect.height / 2 - centre.y - originY;
|
|
256
|
-
return new DOMRect(left, top, width, height);
|
|
257
|
-
}
|
|
258
211
|
|
|
259
212
|
/**
|
|
260
213
|
* The finite animations still running on `layer` and its content. A layer
|
|
@@ -270,48 +223,6 @@ function exitAnimations(layer) {
|
|
|
270
223
|
}).filter(animation => animation.playState === 'running' && animation.effect?.getComputedTiming().endTime !== Infinity);
|
|
271
224
|
}
|
|
272
225
|
|
|
273
|
-
/**
|
|
274
|
-
* The layer's box where its position option put it, without the transform an
|
|
275
|
-
* entry animation (or anything else) applies to it: a Tooltip enters from a
|
|
276
|
-
* few pixels toward its trigger, scaled down, so the transformed box of a
|
|
277
|
-
* tooltip that fits beside its trigger can read as covering it while it
|
|
278
|
-
* enters. The layer's transforms are overridden with `none !important`, which
|
|
279
|
-
* outranks an animation, for this one read and then restored, in the same
|
|
280
|
-
* task: no frame paints in between and the animation keeps running. Where the
|
|
281
|
-
* engine still applies an animated transform under that override (WebKit),
|
|
282
|
-
* the read box has that transform undone instead (`untransform`). A layer
|
|
283
|
-
* that transitions a transform property is not overridden, since restoring the
|
|
284
|
-
* value would start that transition; its box has its transform undone.
|
|
285
|
-
*/
|
|
286
|
-
function settledBox(layer) {
|
|
287
|
-
const view = layer.ownerDocument.defaultView;
|
|
288
|
-
const style = view?.getComputedStyle(layer);
|
|
289
|
-
if (style == null || !hasTransform(style)) {
|
|
290
|
-
return layer.getBoundingClientRect();
|
|
291
|
-
}
|
|
292
|
-
const transitions = style.transitionProperty.split(',').map(p => p.trim());
|
|
293
|
-
const durations = style.transitionDuration.split(',').map(parseFloat);
|
|
294
|
-
const transitioned = transitions.some((name, index) => (name === 'all' || TRANSFORM_PROPERTIES.includes(name)) && (durations[index % durations.length] ?? 0) > 0);
|
|
295
|
-
if (transitioned) {
|
|
296
|
-
return untransform(layer.getBoundingClientRect(), layer, style);
|
|
297
|
-
}
|
|
298
|
-
const saved = TRANSFORM_PROPERTIES.map(name => [name, layer.style.getPropertyValue(name), layer.style.getPropertyPriority(name)]);
|
|
299
|
-
for (const name of TRANSFORM_PROPERTIES) {
|
|
300
|
-
layer.style.setProperty(name, 'none', 'important');
|
|
301
|
-
}
|
|
302
|
-
const box = layer.getBoundingClientRect();
|
|
303
|
-
const under = view?.getComputedStyle(layer);
|
|
304
|
-
const settled = under != null && hasTransform(under) ? untransform(box, layer, under) : box;
|
|
305
|
-
for (const [name, value, priority] of saved) {
|
|
306
|
-
if (value === '') {
|
|
307
|
-
layer.style.removeProperty(name);
|
|
308
|
-
} else {
|
|
309
|
-
layer.style.setProperty(name, value, priority);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return settled;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
226
|
/**
|
|
316
227
|
* Whether the standard list has failed a layer that must keep its anchor
|
|
317
228
|
* clear: its box covers the anchor or, while the anchor is in view, leaves the
|
|
@@ -1258,6 +1169,13 @@ function useLayerImplementation(options) {
|
|
|
1258
1169
|
listenedHandlerRef.current = handler;
|
|
1259
1170
|
}
|
|
1260
1171
|
}, [handleBeforeToggle]);
|
|
1172
|
+
|
|
1173
|
+
// An anchored layer that would run under the software keyboard keeps its
|
|
1174
|
+
// block-start edge and ends clear of the keyboard.
|
|
1175
|
+
const {
|
|
1176
|
+
cap: keyboardCap,
|
|
1177
|
+
followLayerElement
|
|
1178
|
+
} = useLayerKeyboardClearance(isOpen && mode === 'context', popoverRef);
|
|
1261
1179
|
const popoverRefCallback = useCallback(el => {
|
|
1262
1180
|
popoverRef.current = el;
|
|
1263
1181
|
bindToggleListener(el, handleToggle);
|
|
@@ -1268,7 +1186,9 @@ function useLayerImplementation(options) {
|
|
|
1268
1186
|
// Changing a portal target remounts the popover. Preserve the logical
|
|
1269
1187
|
// open state without firing onShow again for the replacement element.
|
|
1270
1188
|
// A show the browser refused during one of its own hides replays once
|
|
1271
|
-
// that hide has ended, for the element still mounted then.
|
|
1189
|
+
// that hide has ended, for the element still mounted then. The
|
|
1190
|
+
// keyboard cap follows the replacement element too.
|
|
1191
|
+
followLayerElement();
|
|
1272
1192
|
if (showPopoverElement(el)) {
|
|
1273
1193
|
if (keepsAnchorClear) {
|
|
1274
1194
|
keepAnchorClear(el, triggerRef.current);
|
|
@@ -1282,7 +1202,7 @@ function useLayerImplementation(options) {
|
|
|
1282
1202
|
});
|
|
1283
1203
|
}
|
|
1284
1204
|
}
|
|
1285
|
-
}, [handleToggle, bindToggleListener, show, showPopoverElement, isCurrentContextPopover, keepsAnchorClear]);
|
|
1205
|
+
}, [handleToggle, bindToggleListener, show, showPopoverElement, isCurrentContextPopover, keepsAnchorClear, followLayerElement]);
|
|
1286
1206
|
const sentinelRefCallback = useCallback(el => {
|
|
1287
1207
|
sentinelRef.current = el;
|
|
1288
1208
|
// A layer that keeps its mount re-resolves it too once it has one.
|
|
@@ -1413,7 +1333,7 @@ function useLayerImplementation(options) {
|
|
|
1413
1333
|
} : {};
|
|
1414
1334
|
const offsetStyle = positioning !== 'anchor' ? null : clearance == null ? placement === 'above' ? styles.farAbove : placement === 'below' ? styles.farBelow : placement === 'start' ? styles.farStart : styles.farEnd : placement === 'above' ? styles.placementAbove(clearance) : placement === 'below' ? styles.placementBelow(clearance) : placement === 'start' ? styles.placementStart(clearance) : styles.placementEnd(clearance);
|
|
1415
1335
|
const viewportStyles = positioning === 'anchor' ? [styles.viewportFit, ...getGutterStyles(placement, alignment)] : null;
|
|
1416
|
-
const stylexResult = stylex.props(layerTextReset.reset, layerStructureReset.reset, styles.base, overlayPaddingReset.reset, viewportStyles, offsetStyle, xstyle);
|
|
1336
|
+
const stylexResult = stylex.props(layerTextReset.reset, layerStructureReset.reset, styles.base, overlayPaddingReset.reset, styles.keyboardCap(keyboardCap == null ? '100vh' : `${keyboardCap}px`, keyboardCap == null ? 'visible' : 'auto'), viewportStyles, offsetStyle, xstyle);
|
|
1417
1337
|
const combinedClassName = extraClassName ? `${extraClassName} ${stylexResult.className ?? ''}` : stylexResult.className;
|
|
1418
1338
|
|
|
1419
1339
|
// The marker gives us the actual JSX parent without mounting arbitrary
|
|
@@ -1422,7 +1342,14 @@ function useLayerImplementation(options) {
|
|
|
1422
1342
|
// The slot renders the layer once the hook has resolved that mount.
|
|
1423
1343
|
const renderLayer = mount => /*#__PURE__*/_jsx(Container, {
|
|
1424
1344
|
ref: popoverRefCallback,
|
|
1425
|
-
id: id
|
|
1345
|
+
id: id
|
|
1346
|
+
// Anchor positioning, as this commit renders it: the software
|
|
1347
|
+
// keyboard caps only an anchored layer, and reads this at
|
|
1348
|
+
// measurement.
|
|
1349
|
+
,
|
|
1350
|
+
...(positioning === 'anchor' ? {
|
|
1351
|
+
[LAYER_ANCHORED_ATTRIBUTE]: ''
|
|
1352
|
+
} : {}),
|
|
1426
1353
|
role: role,
|
|
1427
1354
|
"aria-label": ariaLabel,
|
|
1428
1355
|
popover: lightDismiss ? 'auto' : 'manual',
|
|
@@ -1451,7 +1378,7 @@ function useLayerImplementation(options) {
|
|
|
1451
1378
|
renderLayer: renderLayer,
|
|
1452
1379
|
sentinelRef: sentinelRefCallback
|
|
1453
1380
|
});
|
|
1454
|
-
}, [anchorId, declaredInset, id, isAnchorInView, keepsAnchorClear, lightDismiss, mountStore, popoverRefCallback, sentinelRefCallback]);
|
|
1381
|
+
}, [anchorId, declaredInset, id, isAnchorInView, keepsAnchorClear, keyboardCap, lightDismiss, mountStore, popoverRefCallback, sentinelRefCallback]);
|
|
1455
1382
|
|
|
1456
1383
|
// Render function for fixed mode
|
|
1457
1384
|
const renderFixed = useCallback((children, props) => {
|
|
@@ -1468,7 +1395,10 @@ function useLayerImplementation(options) {
|
|
|
1468
1395
|
top: y,
|
|
1469
1396
|
left: x
|
|
1470
1397
|
};
|
|
1471
|
-
const stylexResult = stylex.props(layerTextReset.reset, layerStructureReset.reset, styles.base, overlayPaddingReset.reset,
|
|
1398
|
+
const stylexResult = stylex.props(layerTextReset.reset, layerStructureReset.reset, styles.base, overlayPaddingReset.reset,
|
|
1399
|
+
// A fixed layer is never capped; it still sets its own limit so it is
|
|
1400
|
+
// not clamped by a capped layer it sits in.
|
|
1401
|
+
styles.keyboardCap('100vh', 'visible'), styles.fixed, xstyle);
|
|
1472
1402
|
const combinedClassName = extraClassName ? `${extraClassName} ${stylexResult.className ?? ''}` : stylexResult.className;
|
|
1473
1403
|
return /*#__PURE__*/_jsx("div", {
|
|
1474
1404
|
ref: popoverRefCallback,
|