@oxyhq/bloom 0.72.0 → 0.72.2
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/lib/commonjs/fonts/FontLoader.node.js +34 -0
- package/lib/commonjs/fonts/FontLoader.node.js.map +1 -0
- package/lib/commonjs/fonts/index.node.js +40 -0
- package/lib/commonjs/fonts/index.node.js.map +1 -0
- package/lib/commonjs/overlay/index.js +53 -32
- package/lib/commonjs/overlay/index.js.map +1 -1
- package/lib/module/fonts/FontLoader.node.js +29 -0
- package/lib/module/fonts/FontLoader.node.js.map +1 -0
- package/lib/module/fonts/index.node.js +22 -0
- package/lib/module/fonts/index.node.js.map +1 -0
- package/lib/module/overlay/index.js +53 -32
- package/lib/module/overlay/index.js.map +1 -1
- package/lib/typescript/commonjs/fonts/FontLoader.node.d.ts +27 -0
- package/lib/typescript/commonjs/fonts/FontLoader.node.d.ts.map +1 -0
- package/lib/typescript/commonjs/fonts/index.node.d.ts +7 -0
- package/lib/typescript/commonjs/fonts/index.node.d.ts.map +1 -0
- package/lib/typescript/commonjs/overlay/index.d.ts +16 -4
- package/lib/typescript/commonjs/overlay/index.d.ts.map +1 -1
- package/lib/typescript/module/fonts/FontLoader.node.d.ts +27 -0
- package/lib/typescript/module/fonts/FontLoader.node.d.ts.map +1 -0
- package/lib/typescript/module/fonts/index.node.d.ts +7 -0
- package/lib/typescript/module/fonts/index.node.d.ts.map +1 -0
- package/lib/typescript/module/overlay/index.d.ts +16 -4
- package/lib/typescript/module/overlay/index.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/__tests__/backdrop-nesting.test.tsx +95 -0
- package/src/fonts/FontLoader.node.tsx +30 -0
- package/src/fonts/index.node.ts +21 -0
- package/src/overlay/index.tsx +47 -31
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.FontLoader = FontLoader;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
/**
|
|
11
|
+
* Node font loader: a pass-through.
|
|
12
|
+
*
|
|
13
|
+
* There is no font registry to load into and no document to inject
|
|
14
|
+
* `@font-face` rules on, so the correct behaviour is to render children and
|
|
15
|
+
* stay out of the way — the same thing `FontLoader.tsx` ends up doing under
|
|
16
|
+
* Node once `applyFontFaces()` hits its `typeof document === 'undefined'`
|
|
17
|
+
* guard.
|
|
18
|
+
*
|
|
19
|
+
* It exists as a separate file rather than reusing that one because
|
|
20
|
+
* `FontLoader.tsx` imports `./apply-font-faces.web` outright, which reaches
|
|
21
|
+
* `font-urls.web`'s `.woff2` imports. Node hands a `.woff2` to the JS parser,
|
|
22
|
+
* so merely LOADING that module is fatal — the guard inside the function never
|
|
23
|
+
* gets a chance to run. Reached only through the `node` export condition on
|
|
24
|
+
* `./fonts`; see `scripts/generate-platform-exports.mjs` for why conditions
|
|
25
|
+
* are the only lever available here.
|
|
26
|
+
*/
|
|
27
|
+
function FontLoader({
|
|
28
|
+
children
|
|
29
|
+
}) {
|
|
30
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
31
|
+
children: children
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=FontLoader.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_jsxRuntime","e","__esModule","default","FontLoader","children","jsx","Fragment"],"sourceRoot":"../../../src","sources":["fonts/FontLoader.node.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAA0B,IAAAC,WAAA,GAAAD,OAAA;AAAA,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAU1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,UAAUA,CAAC;EAAEC;AAA0B,CAAC,EAAE;EACxD,oBAAO,IAAAL,WAAA,CAAAM,GAAA,EAAAN,WAAA,CAAAO,QAAA;IAAAF,QAAA,EAAGA;EAAQ,CAAG,CAAC;AACxB","ignoreList":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "FONT_ASSETS", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _fontAssets.FONT_ASSETS;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "FontLoader", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _FontLoaderNode.FontLoader;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "applyFontFaces", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _applyFontFaces.applyFontFaces;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "fontCssVars", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _tokens.fontCssVars;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "fontFamilies", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _tokens.fontFamilies;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
var _tokens = require("./tokens.js");
|
|
37
|
+
var _applyFontFaces = require("./apply-font-faces");
|
|
38
|
+
var _fontAssets = require("./font-assets");
|
|
39
|
+
var _FontLoaderNode = require("./FontLoader.node.js");
|
|
40
|
+
//# sourceMappingURL=index.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_tokens","require","_applyFontFaces","_fontAssets","_FontLoaderNode"],"sourceRoot":"../../../src","sources":["fonts/index.node.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,IAAAA,OAAA,GAAAC,OAAA;AAEA,IAAAC,eAAA,GAAAD,OAAA;AACA,IAAAE,WAAA,GAAAF,OAAA;AACA,IAAAG,eAAA,GAAAH,OAAA","ignoreList":[]}
|
|
@@ -90,9 +90,21 @@ function OverlayRoot({
|
|
|
90
90
|
}
|
|
91
91
|
OverlayRoot.displayName = 'OverlayRoot';
|
|
92
92
|
/**
|
|
93
|
-
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
94
|
-
*
|
|
95
|
-
*
|
|
93
|
+
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
94
|
+
*
|
|
95
|
+
* The dismiss target is a hit box that fills this component and sits BEHIND
|
|
96
|
+
* `children`, never around them. It used to wrap them, which read fine on
|
|
97
|
+
* native but is invalid on web: the hit box carries `accessibilityRole="button"`,
|
|
98
|
+
* so react-native-web renders it as a real `<button>` — and every control inside
|
|
99
|
+
* any Bloom surface (a dialog's own buttons, a menu's rows) became a nested
|
|
100
|
+
* `<button>`. React reports that as a hydration error, and the nested control's
|
|
101
|
+
* activation behaviour is undefined per the HTML spec.
|
|
102
|
+
*
|
|
103
|
+
* Hit testing is unchanged: the hit box still covers the whole area, `children`
|
|
104
|
+
* render above it and take their own presses, and a press that lands on empty
|
|
105
|
+
* space falls through to the hit box. Layout styles passed via `style` stay on
|
|
106
|
+
* the outer box, so a caller that centres its panel with this component (the
|
|
107
|
+
* centred dialog) keeps doing so.
|
|
96
108
|
*/
|
|
97
109
|
const Backdrop = exports.Backdrop = /*#__PURE__*/(0, _react.memo)(function Backdrop({
|
|
98
110
|
onPress,
|
|
@@ -134,35 +146,44 @@ const Backdrop = exports.Backdrop = /*#__PURE__*/(0, _react.memo)(function Backd
|
|
|
134
146
|
const dimFade = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
|
|
135
147
|
opacity: (progress ? progress.value : 1) * staticOpacity * dimOpacity
|
|
136
148
|
}), [progress, staticOpacity, dimOpacity]);
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
149
|
+
return (
|
|
150
|
+
/*#__PURE__*/
|
|
151
|
+
// `box-none` so this box never takes a press itself: the hit box below and
|
|
152
|
+
// `children` above are what receive them.
|
|
153
|
+
(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
154
|
+
pointerEvents: "box-none",
|
|
155
|
+
style: [_reactNative.StyleSheet.absoluteFill, rootStyle],
|
|
156
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
|
|
157
|
+
pointerEvents: "auto",
|
|
158
|
+
onPress: inert ? undefined : onPress,
|
|
159
|
+
disabled: inert
|
|
160
|
+
// A dimming layer is not a focus stop on web: Escape and the panel's own
|
|
161
|
+
// controls are the keyboard paths out. It stays labelled for screen
|
|
162
|
+
// readers that surface it as the dismiss affordance.
|
|
163
|
+
,
|
|
164
|
+
focusable: false,
|
|
165
|
+
accessibilityRole: inert ? undefined : 'button',
|
|
166
|
+
accessibilityLabel: inert ? undefined : accessibilityLabel,
|
|
167
|
+
testID: testID,
|
|
168
|
+
style: _reactNative.StyleSheet.absoluteFill,
|
|
169
|
+
children: [blurIntensity > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(AnimatedBlurView, {
|
|
170
|
+
intensity: blurIntensity,
|
|
171
|
+
tint: blurTint
|
|
172
|
+
// Android's default blur is a no-op on many devices; this is the
|
|
173
|
+
// implementation that actually renders there.
|
|
174
|
+
,
|
|
175
|
+
experimentalBlurMethod: "dimezisBlurView",
|
|
176
|
+
pointerEvents: "none",
|
|
177
|
+
style: [_reactNative.StyleSheet.absoluteFill, layerStyle, blurFade]
|
|
178
|
+
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
179
|
+
pointerEvents: "none",
|
|
180
|
+
style: [_reactNative.StyleSheet.absoluteFill, {
|
|
181
|
+
backgroundColor: resolvedDimColor
|
|
182
|
+
}, layerStyle, dimFade]
|
|
183
|
+
})]
|
|
184
|
+
}), children]
|
|
185
|
+
})
|
|
186
|
+
);
|
|
166
187
|
});
|
|
167
188
|
Backdrop.displayName = 'Backdrop';
|
|
168
189
|
const styles = _reactNative.StyleSheet.create({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_expoBlur","_reactNative","_reactNativeReanimated","_interopRequireWildcard","_webViewStyle","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","AnimatedBlurView","Animated","createAnimatedComponent","BlurView","BACKDROP_BLUR_INTENSITY","exports","BACKDROP_DIM_OPACITY","OverlayRoot","children","style","testID","jsx","View","pointerEvents","styles","root","displayName","Backdrop","memo","onPress","progress","disabled","blurIntensity","blurTint","dimColor","dimOpacity","layerStyle","accessibilityLabel","inert","flat","StyleSheet","flatten","opacity","styleOpacity","backgroundColor","styleBackground","rootStyle","staticOpacity","resolvedDimColor","blurFade","useAnimatedStyle","value","dimFade","jsxs","Pressable","undefined","focusable","accessibilityRole","
|
|
1
|
+
{"version":3,"names":["_react","require","_expoBlur","_reactNative","_reactNativeReanimated","_interopRequireWildcard","_webViewStyle","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","AnimatedBlurView","Animated","createAnimatedComponent","BlurView","BACKDROP_BLUR_INTENSITY","exports","BACKDROP_DIM_OPACITY","OverlayRoot","children","style","testID","jsx","View","pointerEvents","styles","root","displayName","Backdrop","memo","onPress","progress","disabled","blurIntensity","blurTint","dimColor","dimOpacity","layerStyle","accessibilityLabel","inert","flat","StyleSheet","flatten","opacity","styleOpacity","backgroundColor","styleBackground","rootStyle","staticOpacity","resolvedDimColor","blurFade","useAnimatedStyle","value","dimFade","jsxs","absoluteFill","Pressable","undefined","focusable","accessibilityRole","intensity","tint","experimentalBlurMethod","create","position","Platform","OS","WEB_POSITION_FIXED","top","left","right","bottom"],"sourceRoot":"../../../src","sources":["overlay/index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
/**
|
|
6
|
+
* Node font loader: a pass-through.
|
|
7
|
+
*
|
|
8
|
+
* There is no font registry to load into and no document to inject
|
|
9
|
+
* `@font-face` rules on, so the correct behaviour is to render children and
|
|
10
|
+
* stay out of the way — the same thing `FontLoader.tsx` ends up doing under
|
|
11
|
+
* Node once `applyFontFaces()` hits its `typeof document === 'undefined'`
|
|
12
|
+
* guard.
|
|
13
|
+
*
|
|
14
|
+
* It exists as a separate file rather than reusing that one because
|
|
15
|
+
* `FontLoader.tsx` imports `./apply-font-faces.web` outright, which reaches
|
|
16
|
+
* `font-urls.web`'s `.woff2` imports. Node hands a `.woff2` to the JS parser,
|
|
17
|
+
* so merely LOADING that module is fatal — the guard inside the function never
|
|
18
|
+
* gets a chance to run. Reached only through the `node` export condition on
|
|
19
|
+
* `./fonts`; see `scripts/generate-platform-exports.mjs` for why conditions
|
|
20
|
+
* are the only lever available here.
|
|
21
|
+
*/
|
|
22
|
+
export function FontLoader({
|
|
23
|
+
children
|
|
24
|
+
}) {
|
|
25
|
+
return /*#__PURE__*/_jsx(_Fragment, {
|
|
26
|
+
children: children
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=FontLoader.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Fragment","_Fragment","jsx","_jsx","FontLoader","children"],"sourceRoot":"../../../src","sources":["fonts/FontLoader.node.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AAAC,SAAAC,QAAA,IAAAC,SAAA,EAAAC,GAAA,IAAAC,IAAA;AAU1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAAC;EAAEC;AAA0B,CAAC,EAAE;EACxD,oBAAOF,IAAA,CAAAF,SAAA;IAAAI,QAAA,EAAGA;EAAQ,CAAG,CAAC;AACxB","ignoreList":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Node variant of the `./fonts` barrel, selected by the `node` export
|
|
4
|
+
// condition. Same surface as `./index.ts`, with every member resolved to the
|
|
5
|
+
// inert implementation:
|
|
6
|
+
//
|
|
7
|
+
// - `./apply-font-faces` is the no-op stub. The web one is unreachable here on
|
|
8
|
+
// purpose: it imports `font-urls.web`, whose `.woff2` imports Node feeds to
|
|
9
|
+
// the JS parser, so loading it throws `SyntaxError` before any runtime guard
|
|
10
|
+
// can help.
|
|
11
|
+
// - `./font-assets` is the empty map — there is no native font registry.
|
|
12
|
+
// - `./FontLoader.node` renders children and nothing else.
|
|
13
|
+
//
|
|
14
|
+
// Both platform-forked members are named OUTRIGHT rather than left
|
|
15
|
+
// extensionless, for the same reason `index.web.ts` does it: Node performs no
|
|
16
|
+
// platform-extension resolution, so a bare specifier would fall through to
|
|
17
|
+
// whichever file happens to sit at that path.
|
|
18
|
+
export { fontFamilies, fontCssVars } from "./tokens.js";
|
|
19
|
+
export { applyFontFaces } from './apply-font-faces';
|
|
20
|
+
export { FONT_ASSETS } from './font-assets';
|
|
21
|
+
export { FontLoader } from "./FontLoader.node.js";
|
|
22
|
+
//# sourceMappingURL=index.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["fontFamilies","fontCssVars","applyFontFaces","FONT_ASSETS","FontLoader"],"sourceRoot":"../../../src","sources":["fonts/index.node.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,YAAY,EAAEC,WAAW,QAAQ,aAAU;AAEpD,SAASC,cAAc,QAAQ,oBAAoB;AACnD,SAASC,WAAW,QAAQ,eAAe;AAC3C,SAASC,UAAU,QAAQ,sBAAmB","ignoreList":[]}
|
|
@@ -83,9 +83,21 @@ export function OverlayRoot({
|
|
|
83
83
|
}
|
|
84
84
|
OverlayRoot.displayName = 'OverlayRoot';
|
|
85
85
|
/**
|
|
86
|
-
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
87
|
-
*
|
|
88
|
-
*
|
|
86
|
+
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
87
|
+
*
|
|
88
|
+
* The dismiss target is a hit box that fills this component and sits BEHIND
|
|
89
|
+
* `children`, never around them. It used to wrap them, which read fine on
|
|
90
|
+
* native but is invalid on web: the hit box carries `accessibilityRole="button"`,
|
|
91
|
+
* so react-native-web renders it as a real `<button>` — and every control inside
|
|
92
|
+
* any Bloom surface (a dialog's own buttons, a menu's rows) became a nested
|
|
93
|
+
* `<button>`. React reports that as a hydration error, and the nested control's
|
|
94
|
+
* activation behaviour is undefined per the HTML spec.
|
|
95
|
+
*
|
|
96
|
+
* Hit testing is unchanged: the hit box still covers the whole area, `children`
|
|
97
|
+
* render above it and take their own presses, and a press that lands on empty
|
|
98
|
+
* space falls through to the hit box. Layout styles passed via `style` stay on
|
|
99
|
+
* the outer box, so a caller that centres its panel with this component (the
|
|
100
|
+
* centred dialog) keeps doing so.
|
|
89
101
|
*/
|
|
90
102
|
export const Backdrop = /*#__PURE__*/memo(function Backdrop({
|
|
91
103
|
onPress,
|
|
@@ -127,35 +139,44 @@ export const Backdrop = /*#__PURE__*/memo(function Backdrop({
|
|
|
127
139
|
const dimFade = useAnimatedStyle(() => ({
|
|
128
140
|
opacity: (progress ? progress.value : 1) * staticOpacity * dimOpacity
|
|
129
141
|
}), [progress, staticOpacity, dimOpacity]);
|
|
130
|
-
return
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
142
|
+
return (
|
|
143
|
+
/*#__PURE__*/
|
|
144
|
+
// `box-none` so this box never takes a press itself: the hit box below and
|
|
145
|
+
// `children` above are what receive them.
|
|
146
|
+
_jsxs(View, {
|
|
147
|
+
pointerEvents: "box-none",
|
|
148
|
+
style: [StyleSheet.absoluteFill, rootStyle],
|
|
149
|
+
children: [/*#__PURE__*/_jsxs(Pressable, {
|
|
150
|
+
pointerEvents: "auto",
|
|
151
|
+
onPress: inert ? undefined : onPress,
|
|
152
|
+
disabled: inert
|
|
153
|
+
// A dimming layer is not a focus stop on web: Escape and the panel's own
|
|
154
|
+
// controls are the keyboard paths out. It stays labelled for screen
|
|
155
|
+
// readers that surface it as the dismiss affordance.
|
|
156
|
+
,
|
|
157
|
+
focusable: false,
|
|
158
|
+
accessibilityRole: inert ? undefined : 'button',
|
|
159
|
+
accessibilityLabel: inert ? undefined : accessibilityLabel,
|
|
160
|
+
testID: testID,
|
|
161
|
+
style: StyleSheet.absoluteFill,
|
|
162
|
+
children: [blurIntensity > 0 ? /*#__PURE__*/_jsx(AnimatedBlurView, {
|
|
163
|
+
intensity: blurIntensity,
|
|
164
|
+
tint: blurTint
|
|
165
|
+
// Android's default blur is a no-op on many devices; this is the
|
|
166
|
+
// implementation that actually renders there.
|
|
167
|
+
,
|
|
168
|
+
experimentalBlurMethod: "dimezisBlurView",
|
|
169
|
+
pointerEvents: "none",
|
|
170
|
+
style: [StyleSheet.absoluteFill, layerStyle, blurFade]
|
|
171
|
+
}) : null, /*#__PURE__*/_jsx(Animated.View, {
|
|
172
|
+
pointerEvents: "none",
|
|
173
|
+
style: [StyleSheet.absoluteFill, {
|
|
174
|
+
backgroundColor: resolvedDimColor
|
|
175
|
+
}, layerStyle, dimFade]
|
|
176
|
+
})]
|
|
177
|
+
}), children]
|
|
178
|
+
})
|
|
179
|
+
);
|
|
159
180
|
});
|
|
160
181
|
Backdrop.displayName = 'Backdrop';
|
|
161
182
|
const styles = StyleSheet.create({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["memo","BlurView","Platform","Pressable","StyleSheet","View","Animated","useAnimatedStyle","WEB_POSITION_FIXED","jsx","_jsx","jsxs","_jsxs","AnimatedBlurView","createAnimatedComponent","BACKDROP_BLUR_INTENSITY","BACKDROP_DIM_OPACITY","OverlayRoot","children","style","testID","pointerEvents","styles","root","displayName","Backdrop","onPress","progress","disabled","blurIntensity","blurTint","dimColor","dimOpacity","layerStyle","accessibilityLabel","inert","flat","flatten","opacity","styleOpacity","backgroundColor","styleBackground","rootStyle","staticOpacity","resolvedDimColor","blurFade","value","dimFade","undefined","focusable","accessibilityRole","
|
|
1
|
+
{"version":3,"names":["memo","BlurView","Platform","Pressable","StyleSheet","View","Animated","useAnimatedStyle","WEB_POSITION_FIXED","jsx","_jsx","jsxs","_jsxs","AnimatedBlurView","createAnimatedComponent","BACKDROP_BLUR_INTENSITY","BACKDROP_DIM_OPACITY","OverlayRoot","children","style","testID","pointerEvents","styles","root","displayName","Backdrop","onPress","progress","disabled","blurIntensity","blurTint","dimColor","dimOpacity","layerStyle","accessibilityLabel","inert","flat","flatten","opacity","styleOpacity","backgroundColor","styleBackground","rootStyle","staticOpacity","resolvedDimColor","blurFade","value","dimFade","absoluteFill","undefined","focusable","accessibilityRole","intensity","tint","experimentalBlurMethod","create","position","OS","top","left","right","bottom"],"sourceRoot":"../../../src","sources":["overlay/index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface FontLoaderProps {
|
|
3
|
+
/** Ignored — there is nothing to load. Kept so the API matches every platform. */
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
/** Ignored — nothing is ever pending, so children render immediately. */
|
|
6
|
+
fallback?: React.ReactNode;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Node font loader: a pass-through.
|
|
11
|
+
*
|
|
12
|
+
* There is no font registry to load into and no document to inject
|
|
13
|
+
* `@font-face` rules on, so the correct behaviour is to render children and
|
|
14
|
+
* stay out of the way — the same thing `FontLoader.tsx` ends up doing under
|
|
15
|
+
* Node once `applyFontFaces()` hits its `typeof document === 'undefined'`
|
|
16
|
+
* guard.
|
|
17
|
+
*
|
|
18
|
+
* It exists as a separate file rather than reusing that one because
|
|
19
|
+
* `FontLoader.tsx` imports `./apply-font-faces.web` outright, which reaches
|
|
20
|
+
* `font-urls.web`'s `.woff2` imports. Node hands a `.woff2` to the JS parser,
|
|
21
|
+
* so merely LOADING that module is fatal — the guard inside the function never
|
|
22
|
+
* gets a chance to run. Reached only through the `node` export condition on
|
|
23
|
+
* `./fonts`; see `scripts/generate-platform-exports.mjs` for why conditions
|
|
24
|
+
* are the only lever available here.
|
|
25
|
+
*/
|
|
26
|
+
export declare function FontLoader({ children }: FontLoaderProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
//# sourceMappingURL=FontLoader.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FontLoader.node.d.ts","sourceRoot":"","sources":["../../../../src/fonts/FontLoader.node.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAEvD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { fontFamilies, fontCssVars } from './tokens';
|
|
2
|
+
export type { FontFamilyName } from './tokens';
|
|
3
|
+
export { applyFontFaces } from './apply-font-faces';
|
|
4
|
+
export { FONT_ASSETS } from './font-assets';
|
|
5
|
+
export { FontLoader } from './FontLoader.node';
|
|
6
|
+
export type { FontLoaderProps } from './FontLoader.node';
|
|
7
|
+
//# sourceMappingURL=index.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.node.d.ts","sourceRoot":"","sources":["../../../../src/fonts/index.node.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -103,15 +103,27 @@ export interface BackdropProps {
|
|
|
103
103
|
* express — the web dialog's CSS keyframes, for instance.
|
|
104
104
|
*/
|
|
105
105
|
layerStyle?: StyleProp<ViewStyle>;
|
|
106
|
-
/** Rendered ON TOP of the dim,
|
|
106
|
+
/** Rendered ON TOP of the dim, as a sibling of the press target (Dialog's panel does this). */
|
|
107
107
|
children?: ReactNode;
|
|
108
108
|
accessibilityLabel?: string;
|
|
109
109
|
testID?: string;
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
|
-
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
113
|
-
*
|
|
114
|
-
*
|
|
112
|
+
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
113
|
+
*
|
|
114
|
+
* The dismiss target is a hit box that fills this component and sits BEHIND
|
|
115
|
+
* `children`, never around them. It used to wrap them, which read fine on
|
|
116
|
+
* native but is invalid on web: the hit box carries `accessibilityRole="button"`,
|
|
117
|
+
* so react-native-web renders it as a real `<button>` — and every control inside
|
|
118
|
+
* any Bloom surface (a dialog's own buttons, a menu's rows) became a nested
|
|
119
|
+
* `<button>`. React reports that as a hydration error, and the nested control's
|
|
120
|
+
* activation behaviour is undefined per the HTML spec.
|
|
121
|
+
*
|
|
122
|
+
* Hit testing is unchanged: the hit box still covers the whole area, `children`
|
|
123
|
+
* render above it and take their own presses, and a press that lands on empty
|
|
124
|
+
* space falls through to the hit box. Layout styles passed via `style` stay on
|
|
125
|
+
* the outer box, so a caller that centres its panel with this component (the
|
|
126
|
+
* centred dialog) keeps doing so.
|
|
115
127
|
*/
|
|
116
128
|
export declare const Backdrop: import("react").NamedExoticComponent<BackdropProps>;
|
|
117
129
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAiB,EAAoB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMvF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAiB,EAAoB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMvF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,QAAQ,qDA2EnB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface FontLoaderProps {
|
|
3
|
+
/** Ignored — there is nothing to load. Kept so the API matches every platform. */
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
/** Ignored — nothing is ever pending, so children render immediately. */
|
|
6
|
+
fallback?: React.ReactNode;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Node font loader: a pass-through.
|
|
11
|
+
*
|
|
12
|
+
* There is no font registry to load into and no document to inject
|
|
13
|
+
* `@font-face` rules on, so the correct behaviour is to render children and
|
|
14
|
+
* stay out of the way — the same thing `FontLoader.tsx` ends up doing under
|
|
15
|
+
* Node once `applyFontFaces()` hits its `typeof document === 'undefined'`
|
|
16
|
+
* guard.
|
|
17
|
+
*
|
|
18
|
+
* It exists as a separate file rather than reusing that one because
|
|
19
|
+
* `FontLoader.tsx` imports `./apply-font-faces.web` outright, which reaches
|
|
20
|
+
* `font-urls.web`'s `.woff2` imports. Node hands a `.woff2` to the JS parser,
|
|
21
|
+
* so merely LOADING that module is fatal — the guard inside the function never
|
|
22
|
+
* gets a chance to run. Reached only through the `node` export condition on
|
|
23
|
+
* `./fonts`; see `scripts/generate-platform-exports.mjs` for why conditions
|
|
24
|
+
* are the only lever available here.
|
|
25
|
+
*/
|
|
26
|
+
export declare function FontLoader({ children }: FontLoaderProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
//# sourceMappingURL=FontLoader.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FontLoader.node.d.ts","sourceRoot":"","sources":["../../../../src/fonts/FontLoader.node.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAEvD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { fontFamilies, fontCssVars } from './tokens';
|
|
2
|
+
export type { FontFamilyName } from './tokens';
|
|
3
|
+
export { applyFontFaces } from './apply-font-faces';
|
|
4
|
+
export { FONT_ASSETS } from './font-assets';
|
|
5
|
+
export { FontLoader } from './FontLoader.node';
|
|
6
|
+
export type { FontLoaderProps } from './FontLoader.node';
|
|
7
|
+
//# sourceMappingURL=index.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.node.d.ts","sourceRoot":"","sources":["../../../../src/fonts/index.node.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -103,15 +103,27 @@ export interface BackdropProps {
|
|
|
103
103
|
* express — the web dialog's CSS keyframes, for instance.
|
|
104
104
|
*/
|
|
105
105
|
layerStyle?: StyleProp<ViewStyle>;
|
|
106
|
-
/** Rendered ON TOP of the dim,
|
|
106
|
+
/** Rendered ON TOP of the dim, as a sibling of the press target (Dialog's panel does this). */
|
|
107
107
|
children?: ReactNode;
|
|
108
108
|
accessibilityLabel?: string;
|
|
109
109
|
testID?: string;
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
|
-
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
113
|
-
*
|
|
114
|
-
*
|
|
112
|
+
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
113
|
+
*
|
|
114
|
+
* The dismiss target is a hit box that fills this component and sits BEHIND
|
|
115
|
+
* `children`, never around them. It used to wrap them, which read fine on
|
|
116
|
+
* native but is invalid on web: the hit box carries `accessibilityRole="button"`,
|
|
117
|
+
* so react-native-web renders it as a real `<button>` — and every control inside
|
|
118
|
+
* any Bloom surface (a dialog's own buttons, a menu's rows) became a nested
|
|
119
|
+
* `<button>`. React reports that as a hydration error, and the nested control's
|
|
120
|
+
* activation behaviour is undefined per the HTML spec.
|
|
121
|
+
*
|
|
122
|
+
* Hit testing is unchanged: the hit box still covers the whole area, `children`
|
|
123
|
+
* render above it and take their own presses, and a press that lands on empty
|
|
124
|
+
* space falls through to the hit box. Layout styles passed via `style` stay on
|
|
125
|
+
* the outer box, so a caller that centres its panel with this component (the
|
|
126
|
+
* centred dialog) keeps doing so.
|
|
115
127
|
*/
|
|
116
128
|
export declare const Backdrop: import("react").NamedExoticComponent<BackdropProps>;
|
|
117
129
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAiB,EAAoB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMvF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAiB,EAAoB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMvF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,QAAQ,qDA2EnB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/bloom",
|
|
3
|
-
"version": "0.72.
|
|
3
|
+
"version": "0.72.2",
|
|
4
4
|
"description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -1233,6 +1233,11 @@
|
|
|
1233
1233
|
"import": "./lib/module/fonts/index.web.js",
|
|
1234
1234
|
"require": "./lib/commonjs/fonts/index.web.js"
|
|
1235
1235
|
},
|
|
1236
|
+
"node": {
|
|
1237
|
+
"types": "./lib/typescript/module/fonts/index.node.d.ts",
|
|
1238
|
+
"import": "./lib/module/fonts/index.node.js",
|
|
1239
|
+
"require": "./lib/commonjs/fonts/index.node.js"
|
|
1240
|
+
},
|
|
1236
1241
|
"import": {
|
|
1237
1242
|
"types": "./lib/typescript/module/fonts/index.d.ts",
|
|
1238
1243
|
"default": "./lib/module/fonts/index.js"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// The bug these tests exist for: `Backdrop`'s dismiss target carries
|
|
6
|
+
// `accessibilityRole="button"`, which react-native-web renders as a real
|
|
7
|
+
// `<button>`. While that target WRAPPED `children`, every control inside a
|
|
8
|
+
// Bloom surface became a nested `<button>` — invalid HTML, reported by React as
|
|
9
|
+
// a hydration error, and with activation behaviour the spec leaves undefined.
|
|
10
|
+
// It reproduced on any dialog with a button in it (Mention's post-options menu:
|
|
11
|
+
// "Dismiss Post options" containing "Insights").
|
|
12
|
+
//
|
|
13
|
+
// The fix makes the hit box a SIBLING behind `children`. These tests pin both
|
|
14
|
+
// halves of that: no nesting, and the dismiss press still works.
|
|
15
|
+
|
|
16
|
+
import { createElement } from 'react';
|
|
17
|
+
import { act } from 'react';
|
|
18
|
+
import { createRoot, type Root } from 'react-dom/client';
|
|
19
|
+
|
|
20
|
+
// The whole point is what react-native-web puts in the DOM, so this suite runs
|
|
21
|
+
// against the REAL RNW — the repo-wide `react-native` mock emits no host
|
|
22
|
+
// elements and would make every assertion below vacuous.
|
|
23
|
+
jest.mock('react-native', () => jest.requireActual('react-native-web'));
|
|
24
|
+
|
|
25
|
+
import { Pressable, Text } from 'react-native';
|
|
26
|
+
|
|
27
|
+
import { Backdrop } from '../overlay';
|
|
28
|
+
|
|
29
|
+
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
|
30
|
+
|
|
31
|
+
function render(node: ReturnType<typeof createElement>): { root: Root; container: HTMLElement } {
|
|
32
|
+
const container = document.createElement('div');
|
|
33
|
+
document.body.appendChild(container);
|
|
34
|
+
const root = createRoot(container);
|
|
35
|
+
act(() => {
|
|
36
|
+
root.render(node);
|
|
37
|
+
});
|
|
38
|
+
return { root, container };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe('Backdrop DOM nesting (web)', () => {
|
|
42
|
+
it('does not make a pressable child a nested <button>', () => {
|
|
43
|
+
const { root, container } = render(
|
|
44
|
+
createElement(Backdrop, {
|
|
45
|
+
onPress: () => {},
|
|
46
|
+
accessibilityLabel: 'Dismiss Post options',
|
|
47
|
+
testID: 'backdrop',
|
|
48
|
+
children: createElement(
|
|
49
|
+
Pressable,
|
|
50
|
+
{ accessibilityRole: 'button', accessibilityLabel: 'Insights', onPress: () => {} },
|
|
51
|
+
createElement(Text, null, 'Insights'),
|
|
52
|
+
),
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Vacuity floor: the child button must actually be in the DOM, otherwise
|
|
57
|
+
// "no nesting" would pass on an empty tree.
|
|
58
|
+
const inner = container.querySelector('[aria-label="Insights"]');
|
|
59
|
+
expect(inner?.tagName).toBe('BUTTON');
|
|
60
|
+
expect(container.querySelector('[aria-label="Dismiss Post options"]')?.tagName).toBe('BUTTON');
|
|
61
|
+
|
|
62
|
+
expect(container.querySelectorAll('button button')).toHaveLength(0);
|
|
63
|
+
|
|
64
|
+
act(() => root.unmount());
|
|
65
|
+
container.remove();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('still dismisses when the backdrop itself is pressed', () => {
|
|
69
|
+
const onPress = jest.fn();
|
|
70
|
+
const { root, container } = render(
|
|
71
|
+
createElement(Backdrop, { onPress, accessibilityLabel: 'Dismiss dialog', children: null }),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const hitBox = container.querySelector<HTMLElement>('[aria-label="Dismiss dialog"]');
|
|
75
|
+
expect(hitBox).not.toBeNull();
|
|
76
|
+
act(() => {
|
|
77
|
+
hitBox?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
78
|
+
});
|
|
79
|
+
expect(onPress).toHaveBeenCalledTimes(1);
|
|
80
|
+
|
|
81
|
+
act(() => root.unmount());
|
|
82
|
+
container.remove();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('emits no dismiss affordance at all when inert', () => {
|
|
86
|
+
const { root, container } = render(
|
|
87
|
+
createElement(Backdrop, { disabled: true, onPress: () => {}, children: null }),
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
expect(container.querySelectorAll('button')).toHaveLength(0);
|
|
91
|
+
|
|
92
|
+
act(() => root.unmount());
|
|
93
|
+
container.remove();
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export interface FontLoaderProps {
|
|
4
|
+
/** Ignored — there is nothing to load. Kept so the API matches every platform. */
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
/** Ignored — nothing is ever pending, so children render immediately. */
|
|
7
|
+
fallback?: React.ReactNode;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Node font loader: a pass-through.
|
|
13
|
+
*
|
|
14
|
+
* There is no font registry to load into and no document to inject
|
|
15
|
+
* `@font-face` rules on, so the correct behaviour is to render children and
|
|
16
|
+
* stay out of the way — the same thing `FontLoader.tsx` ends up doing under
|
|
17
|
+
* Node once `applyFontFaces()` hits its `typeof document === 'undefined'`
|
|
18
|
+
* guard.
|
|
19
|
+
*
|
|
20
|
+
* It exists as a separate file rather than reusing that one because
|
|
21
|
+
* `FontLoader.tsx` imports `./apply-font-faces.web` outright, which reaches
|
|
22
|
+
* `font-urls.web`'s `.woff2` imports. Node hands a `.woff2` to the JS parser,
|
|
23
|
+
* so merely LOADING that module is fatal — the guard inside the function never
|
|
24
|
+
* gets a chance to run. Reached only through the `node` export condition on
|
|
25
|
+
* `./fonts`; see `scripts/generate-platform-exports.mjs` for why conditions
|
|
26
|
+
* are the only lever available here.
|
|
27
|
+
*/
|
|
28
|
+
export function FontLoader({ children }: FontLoaderProps) {
|
|
29
|
+
return <>{children}</>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Node variant of the `./fonts` barrel, selected by the `node` export
|
|
2
|
+
// condition. Same surface as `./index.ts`, with every member resolved to the
|
|
3
|
+
// inert implementation:
|
|
4
|
+
//
|
|
5
|
+
// - `./apply-font-faces` is the no-op stub. The web one is unreachable here on
|
|
6
|
+
// purpose: it imports `font-urls.web`, whose `.woff2` imports Node feeds to
|
|
7
|
+
// the JS parser, so loading it throws `SyntaxError` before any runtime guard
|
|
8
|
+
// can help.
|
|
9
|
+
// - `./font-assets` is the empty map — there is no native font registry.
|
|
10
|
+
// - `./FontLoader.node` renders children and nothing else.
|
|
11
|
+
//
|
|
12
|
+
// Both platform-forked members are named OUTRIGHT rather than left
|
|
13
|
+
// extensionless, for the same reason `index.web.ts` does it: Node performs no
|
|
14
|
+
// platform-extension resolution, so a bare specifier would fall through to
|
|
15
|
+
// whichever file happens to sit at that path.
|
|
16
|
+
export { fontFamilies, fontCssVars } from './tokens';
|
|
17
|
+
export type { FontFamilyName } from './tokens';
|
|
18
|
+
export { applyFontFaces } from './apply-font-faces';
|
|
19
|
+
export { FONT_ASSETS } from './font-assets';
|
|
20
|
+
export { FontLoader } from './FontLoader.node';
|
|
21
|
+
export type { FontLoaderProps } from './FontLoader.node';
|
package/src/overlay/index.tsx
CHANGED
|
@@ -124,16 +124,28 @@ export interface BackdropProps {
|
|
|
124
124
|
* express — the web dialog's CSS keyframes, for instance.
|
|
125
125
|
*/
|
|
126
126
|
layerStyle?: StyleProp<ViewStyle>;
|
|
127
|
-
/** Rendered ON TOP of the dim,
|
|
127
|
+
/** Rendered ON TOP of the dim, as a sibling of the press target (Dialog's panel does this). */
|
|
128
128
|
children?: ReactNode;
|
|
129
129
|
accessibilityLabel?: string;
|
|
130
130
|
testID?: string;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
135
|
-
*
|
|
136
|
-
*
|
|
134
|
+
* Full-bleed blur + dim that dismisses the surface when pressed.
|
|
135
|
+
*
|
|
136
|
+
* The dismiss target is a hit box that fills this component and sits BEHIND
|
|
137
|
+
* `children`, never around them. It used to wrap them, which read fine on
|
|
138
|
+
* native but is invalid on web: the hit box carries `accessibilityRole="button"`,
|
|
139
|
+
* so react-native-web renders it as a real `<button>` — and every control inside
|
|
140
|
+
* any Bloom surface (a dialog's own buttons, a menu's rows) became a nested
|
|
141
|
+
* `<button>`. React reports that as a hydration error, and the nested control's
|
|
142
|
+
* activation behaviour is undefined per the HTML spec.
|
|
143
|
+
*
|
|
144
|
+
* Hit testing is unchanged: the hit box still covers the whole area, `children`
|
|
145
|
+
* render above it and take their own presses, and a press that lands on empty
|
|
146
|
+
* space falls through to the hit box. Layout styles passed via `style` stay on
|
|
147
|
+
* the outer box, so a caller that centres its panel with this component (the
|
|
148
|
+
* centred dialog) keeps doing so.
|
|
137
149
|
*/
|
|
138
150
|
export const Backdrop = memo(function Backdrop({
|
|
139
151
|
onPress,
|
|
@@ -175,36 +187,40 @@ export const Backdrop = memo(function Backdrop({
|
|
|
175
187
|
);
|
|
176
188
|
|
|
177
189
|
return (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
190
|
+
// `box-none` so this box never takes a press itself: the hit box below and
|
|
191
|
+
// `children` above are what receive them.
|
|
192
|
+
<View pointerEvents="box-none" style={[StyleSheet.absoluteFill, rootStyle]}>
|
|
193
|
+
<Pressable
|
|
194
|
+
pointerEvents="auto"
|
|
195
|
+
onPress={inert ? undefined : onPress}
|
|
196
|
+
disabled={inert}
|
|
197
|
+
// A dimming layer is not a focus stop on web: Escape and the panel's own
|
|
198
|
+
// controls are the keyboard paths out. It stays labelled for screen
|
|
199
|
+
// readers that surface it as the dismiss affordance.
|
|
200
|
+
focusable={false}
|
|
201
|
+
accessibilityRole={inert ? undefined : 'button'}
|
|
202
|
+
accessibilityLabel={inert ? undefined : accessibilityLabel}
|
|
203
|
+
testID={testID}
|
|
204
|
+
style={StyleSheet.absoluteFill}
|
|
205
|
+
>
|
|
206
|
+
{blurIntensity > 0 ? (
|
|
207
|
+
<AnimatedBlurView
|
|
208
|
+
intensity={blurIntensity}
|
|
209
|
+
tint={blurTint}
|
|
210
|
+
// Android's default blur is a no-op on many devices; this is the
|
|
211
|
+
// implementation that actually renders there.
|
|
212
|
+
experimentalBlurMethod="dimezisBlurView"
|
|
213
|
+
pointerEvents="none"
|
|
214
|
+
style={[StyleSheet.absoluteFill, layerStyle, blurFade]}
|
|
215
|
+
/>
|
|
216
|
+
) : null}
|
|
217
|
+
<Animated.View
|
|
198
218
|
pointerEvents="none"
|
|
199
|
-
style={[StyleSheet.absoluteFill, layerStyle,
|
|
219
|
+
style={[StyleSheet.absoluteFill, { backgroundColor: resolvedDimColor }, layerStyle, dimFade]}
|
|
200
220
|
/>
|
|
201
|
-
|
|
202
|
-
<Animated.View
|
|
203
|
-
pointerEvents="none"
|
|
204
|
-
style={[StyleSheet.absoluteFill, { backgroundColor: resolvedDimColor }, layerStyle, dimFade]}
|
|
205
|
-
/>
|
|
221
|
+
</Pressable>
|
|
206
222
|
{children}
|
|
207
|
-
</
|
|
223
|
+
</View>
|
|
208
224
|
);
|
|
209
225
|
});
|
|
210
226
|
|