feat: add web platform support using CSS backdrop-filter#94
feat: add web platform support using CSS backdrop-filter#94Navipro70 wants to merge 5 commits intosbaiahmed1:mainfrom
Conversation
Implements web versions of all components using platform-specific `.web.tsx` files that are automatically resolved by Metro/webpack when bundling for web. Components implemented: - BlurView: CSS backdrop-filter with blurType → background tint mapping - VibrancyView: Falls back to BlurView (same as Android) - ProgressiveBlurView: backdrop-filter + CSS mask-image gradients - LiquidGlassView: backdrop-filter with blur + saturate glass effect - LiquidGlassContainer: Plain View with gap spacing - BlurSwitch: React Native Switch component All 21 BlurType values are mapped to appropriate rgba background colours that approximate native iOS UIVisualEffectView tints. Closes sbaiahmed1#79
|
Caution Review failedAn error occurred during the review process. Please try again later. 📝 WalkthroughWalkthroughAdds web-specific implementations and a web entrypoint for blur/glass UI components: Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Hello @Navipro70 @DanielAraldi someone got before you 😜 |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (3)
src/VibrancyView.web.tsx (1)
20-36: Missingexport default— inconsistent with every other.web.tsxfile in this PR.
BlurView.web.tsx,ProgressiveBlurView.web.tsx,LiquidGlassView.web.tsx, andBlurSwitch.web.tsxall carry aexport defaultalias.VibrancyView.web.tsxdoes not, which is inconsistent without a clear reason.♻️ Proposed addition
export const VibrancyView: React.FC<VibrancyViewProps> = ({ ... }) => { ... }; + +export default VibrancyView;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/VibrancyView.web.tsx` around lines 20 - 36, The file exports a named component VibrancyView (with props VibrancyViewProps) but lacks a default export like the other .web.tsx files; add a default export for consistency by exporting VibrancyView as the module default (e.g., append or change to export default VibrancyView) so consumers can import it the same way as BlurView.web.tsx, ProgressiveBlurView.web.tsx, LiquidGlassView.web.tsx, and BlurSwitch.web.tsx.src/LiquidGlassView.web.tsx (1)
25-25: Consider narrowingglassTintColor's type to make the'clear'sentinel discoverable.The default value
'clear'acts as an undocumented sentinel but the prop is typed asstring, making it invisible to consumers via TypeScript. ConsiderglassTintColor?: 'clear' | (string & {})so'clear'autocompletes while still accepting arbitrary CSS color strings.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/LiquidGlassView.web.tsx` at line 25, The prop type for glassTintColor is currently typed as string which hides the default sentinel 'clear'; update the prop/interface/type declaration (where glassTintColor is defined, e.g., the LiquidGlassView props type and any related PropTypes) to glassTintColor?: 'clear' | (string & {}) so that 'clear' is suggested by autocomplete while still allowing arbitrary CSS color strings, and keep the default value glassTintColor = 'clear' unchanged.src/LiquidGlassContainer.web.tsx (1)
24-24: Optional:gapis a typedViewStyleprop in React Native ≥ 0.71 — cast can be dropped.The project targets React Native 0.79.2, which is well above RN 0.71 where
FlexStyleaddedgap?: number. Theas Record<string, unknown>cast is unnecessary and suppresses type safety on the entire object.♻️ Proposed cleanup
- style={[{ gap: spacing } as Record<string, unknown>, style]} + style={[{ gap: spacing }, style]}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/LiquidGlassContainer.web.tsx` at line 24, Remove the unnecessary cast on the inline style object so the gap property keeps its proper typed ViewStyle/FlexStyle type: in LiquidGlassContainer.web.tsx locate the JSX where style is set (style={[{ gap: spacing } as Record<string, unknown>, style]}) and replace it with the plain object form that includes gap (e.g., style={[{ gap: spacing }, style]}) so TypeScript uses the correct RN FlexStyle gap typing instead of erasing types with Record<string, unknown>.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/BlurView.web.tsx`:
- Around line 85-92: In the BlurView no-children branch (the if that checks
Children.count(children)), the style array currently places blurStyle after
overlay so blurStyle.backgroundColor overrides the caller-supplied
overlay.backgroundColor; change the render to ensure the caller overlayColor
wins by either swapping the order so overlay is last in the style array or by
merging overlay.backgroundColor into blurStyle (preserving other blurStyle
properties) before applying styles; update the branch that returns <View
style={[style, overlay, blurStyle as Record<string, unknown>]} {...props} /> so
overlayColor is not silently ignored.
- Around line 97-100: Remove the ad-hoc cast in the JSX array and properly type
the blur style: replace style={[StyleSheet.absoluteFill, blurStyle as
Record<string, unknown>]} with style={[StyleSheet.absoluteFill, blurStyle]} and
change the declaration of blurStyle to a proper React Native style type (e.g.,
StyleProp<ViewStyle> / ViewStyle) in the BlurView component (or file) so no
inline cast is needed; alternatively, if a cast is required, use blurStyle as
ViewStyle instead of Record<string, unknown> to satisfy ESLint/Prettier.
In `@src/index.web.tsx`:
- Around line 5-7: Prettier/ESLint flags the multi-line type export for
ProgressiveBlurDirection; change the export to a single-line form without the
trailing comma so it formats correctly — update the export of
ProgressiveBlurDirection from ReactNativeProgressiveBlurViewNativeComponent to a
compact one-line export (replace the current multi-line block surrounding
ProgressiveBlurDirection).
In `@src/LiquidGlassView.web.tsx`:
- Around line 36-46: The tint color computation double-applies glassOpacity when
glassTintColor === 'clear', causing quadratic alpha; update the 'clear' branch
in the tintColor calculation so the alpha is the fixed base 0.15 (not 0.15 *
glassOpacity) and let glassStyle.opacity = glassOpacity uniformly control
overall transparency; locate the tintColor and glassStyle definitions (the
tintColor ternary and the glassStyle object) and remove the pre-multiplication
so the rgba uses 0.15 alpha and opacity remains glassOpacity.
In `@src/ProgressiveBlurView.web.tsx`:
- Around line 114-117: The array passed to the style prop combines
StyleSheet.absoluteFill and blurStyle with an unnecessary type cast that
triggers Prettier/ESLint formatting errors; update the style assignment in
ProgressiveBlurView.web.tsx to pass a single merged object or an array without
the "as Record<string, unknown>" cast (e.g., merge StyleSheet.absoluteFill and
blurStyle into one object or ensure blurStyle has the correct type), keeping the
reference to StyleSheet.absoluteFill and blurStyle so the linter no longer flags
formatting/type-cast issues.
- Around line 111-121: ProgressiveBlurView's render places children directly in
the root container, which can sit beneath the absolute-fill blur on some web
stacking contexts; update the StyleSheet.create block used by
ProgressiveBlurView.web.tsx to add a children style with zIndex: 1 (matching
BlurView's pattern) and then wrap the {children} return branch in a <View
style={styles.children}> so children are always painted above the blur layer;
update references to styles.children where the component returns its JSX
(component: ProgressiveBlurView) and ensure the new style is included in the
exported styles object.
- Around line 21-43: The duplicate blurTypeToBackground constant should be
extracted into a shared module and imported by both consumers: create a new
module (e.g., blurTypeUtils.web.ts) that exports blurTypeToBackground (using the
BlurType type from ReactNativeBlurViewNativeComponent), move the full
Record<BlurType, string> mapping there, then remove the local
blurTypeToBackground definitions from ProgressiveBlurView.web.tsx and
BlurView.web.tsx and replace them with an import like `import {
blurTypeToBackground } from './blurTypeUtils.web'`; ensure the new module
exports the same symbol name and that both files import the BlurType type if
needed for typings.
- Around line 50-65: The getMaskGradient function has an inversion bug for the
'blurredCenterClearTopAndBottom' case because start and end are computed once
and can produce start> end; update the switch so that the
'blurredCenterClearTopAndBottom' branch computes its own block-scoped
clampedOffset = Math.max(0, Math.min(startOffset, 0.5)), then compute start =
`${Math.round(clampedOffset * 100)}%` and end = `${100 -
Math.round(clampedOffset * 100)}%` before returning the gradient string; also
add a default case that returns a safe fallback (e.g., empty string) to handle
unknown ProgressiveBlurDirection values.
---
Nitpick comments:
In `@src/LiquidGlassContainer.web.tsx`:
- Line 24: Remove the unnecessary cast on the inline style object so the gap
property keeps its proper typed ViewStyle/FlexStyle type: in
LiquidGlassContainer.web.tsx locate the JSX where style is set (style={[{ gap:
spacing } as Record<string, unknown>, style]}) and replace it with the plain
object form that includes gap (e.g., style={[{ gap: spacing }, style]}) so
TypeScript uses the correct RN FlexStyle gap typing instead of erasing types
with Record<string, unknown>.
In `@src/LiquidGlassView.web.tsx`:
- Line 25: The prop type for glassTintColor is currently typed as string which
hides the default sentinel 'clear'; update the prop/interface/type declaration
(where glassTintColor is defined, e.g., the LiquidGlassView props type and any
related PropTypes) to glassTintColor?: 'clear' | (string & {}) so that 'clear'
is suggested by autocomplete while still allowing arbitrary CSS color strings,
and keep the default value glassTintColor = 'clear' unchanged.
In `@src/VibrancyView.web.tsx`:
- Around line 20-36: The file exports a named component VibrancyView (with props
VibrancyViewProps) but lacks a default export like the other .web.tsx files; add
a default export for consistency by exporting VibrancyView as the module default
(e.g., append or change to export default VibrancyView) so consumers can import
it the same way as BlurView.web.tsx, ProgressiveBlurView.web.tsx,
LiquidGlassView.web.tsx, and BlurSwitch.web.tsx.
|
Hey @Navipro70, thank you so much for helping us with web support, thank you very much!! I will test this and merge it as soon as possible 🫡❤️ |
|
Hey @DanielAraldi did you test it ? Still working on all plateforms ? ( for easy testing try expo ) |
There was a problem hiding this comment.
♻️ Duplicate comments (3)
src/ProgressiveBlurView.web.tsx (1)
107-122:⚠️ Potential issue | 🟠 MajorCenter-direction gradient can invert/collapse for larger
startOffset.In
blurredCenterClearTopAndBottom,startOffsetis not clamped, so values above0.5producestart > endand break the intended center mask shape. Also, adding adefaultfallback avoids undefined returns.🐛 Proposed fix
const getMaskGradient = ( direction: ProgressiveBlurDirection, startOffset: number ): string => { - const start = `${Math.round(startOffset * 100)}%`; - const end = `${100 - Math.round(startOffset * 100)}%`; + const clamped = Math.max(0, Math.min(startOffset, 1)); + const start = `${Math.round(clamped * 100)}%`; + const end = `${100 - Math.round(clamped * 100)}%`; switch (direction) { case 'blurredTopClearBottom': return `linear-gradient(to bottom, black ${start}, transparent 100%)`; case 'blurredBottomClearTop': return `linear-gradient(to top, black ${start}, transparent 100%)`; - case 'blurredCenterClearTopAndBottom': - return `linear-gradient(to bottom, transparent 0%, black ${start}, black ${end}, transparent 100%)`; + case 'blurredCenterClearTopAndBottom': { + const centerOffset = Math.max(0, Math.min(clamped, 0.5)); + const centerStart = `${Math.round(centerOffset * 100)}%`; + const centerEnd = `${100 - Math.round(centerOffset * 100)}%`; + return `linear-gradient(to bottom, transparent 0%, black ${centerStart}, black ${centerEnd}, transparent 100%)`; + } + default: + return 'linear-gradient(to bottom, black 0%, transparent 100%)'; } };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ProgressiveBlurView.web.tsx` around lines 107 - 122, The getMaskGradient function can return invalid gradients when startOffset > 0.5 (start > end) and may return undefined for unknown directions; clamp startOffset to the [0, 0.5] range before computing start/end so the center mask never inverts (adjust calculations used in the 'blurredCenterClearTopAndBottom' case), and add a default/fallback return (e.g., a no-op or single-direction gradient) to ensure getMaskGradient always returns a string; update references in the getMaskGradient function and the 'blurredCenterClearTopAndBottom' branch accordingly.src/BlurView.web.tsx (1)
145-147:⚠️ Potential issue | 🟡 Minor
overlayColoris overridden whenchildrenis absent.On Line 146,
[style, overlay, blurStyle]makesblurStyle.backgroundColorwin, sooverlayColoris silently ignored in this branch.🐛 Proposed fix
- return <View style={[style, overlay, blurStyle]} {...props} />; + return <View style={[style, blurStyle, overlay]} {...props} />;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/BlurView.web.tsx` around lines 145 - 147, When children are absent the View is rendered with styles in the order [style, overlay, blurStyle], causing blurStyle.backgroundColor to override overlayColor; fix by ensuring overlay styles are applied last so overlayColor wins (e.g., change the array order to [style, blurStyle, overlay] or merge overlay into the final style object) in the branch that returns <View ... />; look for Children.count(children) and the returned View using style, overlay, blurStyle to update the ordering so overlayColor is not silently ignored.src/LiquidGlassView.web.tsx (1)
120-130:⚠️ Potential issue | 🟠 Major
glassOpacityis double-applied in the'clear'tint branch.Line 122 pre-multiplies alpha by
glassOpacity, then Line 129 appliesopacity: glassOpacityagain. This makes the clear tint fade quadratically.🐛 Proposed fix
const tintColor = glassTintColor === 'clear' - ? `rgba(255, 255, 255, ${0.15 * glassOpacity})` + ? 'rgba(255, 255, 255, 0.15)' : glassTintColor;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/LiquidGlassView.web.tsx` around lines 120 - 130, The clear-tint branch multiplies alpha by glassOpacity and then glassOpacity is applied again via glassStyle.opacity, causing quadratic fading; change the 'clear' branch in tintColor so it uses a fixed alpha (e.g. 0.15) instead of pre-multiplying by glassOpacity (keep glassStyle.opacity: glassOpacity), i.e. update the computation that sets tintColor (and thus backgroundColor) so it no longer multiplies by glassOpacity; refer to tintColor, glassTintColor, glassOpacity, and glassStyle.backgroundColor/opacity when making the change.
🧹 Nitpick comments (1)
src/BlurSwitch.tsx (1)
32-33: Inconsistent platform tag casing.The
@platformtag on line 32 is now capitalized to "Android", but line 41 still uses lowercase "ios". For consistency, consider using proper casing for both platforms: "Android" and "iOS".📝 Suggested fix for consistency
* `@description` The color of the switch thumb * - * `@platform` ios + * `@platform` iOS * `@default` '#FFFFFF'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/BlurSwitch.tsx` around lines 32 - 33, The JSDoc platform tags in BlurSwitch.tsx are inconsistent (one uses "Android", another "ios"); update the `@platform` tags in the component's JSDoc to use consistent casing "Android" and "iOS" (capitalize the I) so both tags match; locate the JSDoc block above the BlurSwitch component or export and change "ios" to "iOS".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/BlurView.web.tsx`:
- Around line 145-147: When children are absent the View is rendered with styles
in the order [style, overlay, blurStyle], causing blurStyle.backgroundColor to
override overlayColor; fix by ensuring overlay styles are applied last so
overlayColor wins (e.g., change the array order to [style, blurStyle, overlay]
or merge overlay into the final style object) in the branch that returns <View
... />; look for Children.count(children) and the returned View using style,
overlay, blurStyle to update the ordering so overlayColor is not silently
ignored.
In `@src/LiquidGlassView.web.tsx`:
- Around line 120-130: The clear-tint branch multiplies alpha by glassOpacity
and then glassOpacity is applied again via glassStyle.opacity, causing quadratic
fading; change the 'clear' branch in tintColor so it uses a fixed alpha (e.g.
0.15) instead of pre-multiplying by glassOpacity (keep glassStyle.opacity:
glassOpacity), i.e. update the computation that sets tintColor (and thus
backgroundColor) so it no longer multiplies by glassOpacity; refer to tintColor,
glassTintColor, glassOpacity, and glassStyle.backgroundColor/opacity when making
the change.
In `@src/ProgressiveBlurView.web.tsx`:
- Around line 107-122: The getMaskGradient function can return invalid gradients
when startOffset > 0.5 (start > end) and may return undefined for unknown
directions; clamp startOffset to the [0, 0.5] range before computing start/end
so the center mask never inverts (adjust calculations used in the
'blurredCenterClearTopAndBottom' case), and add a default/fallback return (e.g.,
a no-op or single-direction gradient) to ensure getMaskGradient always returns a
string; update references in the getMaskGradient function and the
'blurredCenterClearTopAndBottom' branch accordingly.
---
Nitpick comments:
In `@src/BlurSwitch.tsx`:
- Around line 32-33: The JSDoc platform tags in BlurSwitch.tsx are inconsistent
(one uses "Android", another "ios"); update the `@platform` tags in the
component's JSDoc to use consistent casing "Android" and "iOS" (capitalize the
I) so both tags match; locate the JSDoc block above the BlurSwitch component or
export and change "ios" to "iOS".
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
src/BlurSwitch.tsxsrc/BlurSwitch.web.tsxsrc/BlurView.web.tsxsrc/LiquidGlassContainer.tsxsrc/LiquidGlassContainer.web.tsxsrc/LiquidGlassView.tsxsrc/LiquidGlassView.web.tsxsrc/ProgressiveBlurView.tsxsrc/ProgressiveBlurView.web.tsxsrc/index.web.tsx
✅ Files skipped from review due to trivial changes (1)
- src/ProgressiveBlurView.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- src/LiquidGlassContainer.web.tsx
- src/index.web.tsx
- src/BlurSwitch.web.tsx
I'm testing now haha |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/ProgressiveBlurView.web.tsx (1)
107-122:⚠️ Potential issue | 🟠 Major
blurredCenterClearTopAndBottomcan generate inverted stops for highstartOffset.For values above
0.5,start > end, which collapses the center band. Clamp center offset to[0, 0.5]and add a safe default branch.Suggested fix
const getMaskGradient = ( direction: ProgressiveBlurDirection, startOffset: number ): string => { - const start = `${Math.round(startOffset * 100)}%`; - const end = `${100 - Math.round(startOffset * 100)}%`; + const clamped = Math.max(0, Math.min(startOffset, 1)); + const start = `${Math.round(clamped * 100)}%`; + const end = `${100 - Math.round(clamped * 100)}%`; switch (direction) { case 'blurredTopClearBottom': return `linear-gradient(to bottom, black ${start}, transparent 100%)`; case 'blurredBottomClearTop': return `linear-gradient(to top, black ${start}, transparent 100%)`; - case 'blurredCenterClearTopAndBottom': - return `linear-gradient(to bottom, transparent 0%, black ${start}, black ${end}, transparent 100%)`; + case 'blurredCenterClearTopAndBottom': { + const centerOffset = Math.max(0, Math.min(clamped, 0.5)); + const cStart = `${Math.round(centerOffset * 100)}%`; + const cEnd = `${100 - Math.round(centerOffset * 100)}%`; + return `linear-gradient(to bottom, transparent 0%, black ${cStart}, black ${cEnd}, transparent 100%)`; + } + default: + return `linear-gradient(to bottom, black ${start}, transparent 100%)`; } };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ProgressiveBlurView.web.tsx` around lines 107 - 122, getMaskGradient can produce inverted/overlapping gradient stops when startOffset > 0.5; clamp the center offset to the range [0, 0.5] before computing percentages and compute start/end from that clamped value (e.g., let c = Math.min(Math.max(startOffset, 0), 0.5); start = `${Math.round(c*100)}%`; end = `${100 - Math.round(c*100)}%`), update the 'blurredCenterClearTopAndBottom' branch to use those clamped values, and add a safe default return for unknown ProgressiveBlurDirection values so the function always returns a valid gradient string (reference: getMaskGradient and ProgressiveBlurDirection).src/BlurView.web.tsx (1)
146-148:⚠️ Potential issue | 🟡 Minor
overlayColoris still overridden whenchildrenis empty.On Line 147,
blurStyle.backgroundColorwins because it comes afteroverlayin the style array, so caller-providedoverlayColoris effectively ignored in this branch.Suggested fix
- return <View style={[style, overlay, blurStyle]} {...props} />; + return <View style={[style, blurStyle, overlay]} {...props} />;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/BlurView.web.tsx` around lines 146 - 148, The branch that returns <View style={[style, overlay, blurStyle]} {...props} /> overrides caller overlayColor because blurStyle.bgColor comes after overlay; update the style order or merge overlayColor into the last style so caller overlayColor wins — specifically in the empty-children branch (the code using Children.count(children) and returning View), change the style array to put blurStyle before overlay (e.g. [style, blurStyle, overlay]) or ensure overlay.backgroundColor is assigned from the overlayColor prop and used as the last item so overlayColor is not overwritten.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/ProgressiveBlurView.web.tsx`:
- Around line 188-190: In the no-children render path the style array order
causes blurStyle.backgroundColor to override the passed-in overlayColor; in the
conditional branch that returns <View ... /> when Children.count(children) is
zero, reorder the style array so overlay is last (e.g., change [style, overlay,
blurStyle] to [style, blurStyle, overlay]) so the overlay prop wins; update the
return in ProgressiveBlurView.web.tsx where Children.count(children) is checked
and ensure the same ordering convention is used consistently.
---
Duplicate comments:
In `@src/BlurView.web.tsx`:
- Around line 146-148: The branch that returns <View style={[style, overlay,
blurStyle]} {...props} /> overrides caller overlayColor because
blurStyle.bgColor comes after overlay; update the style order or merge
overlayColor into the last style so caller overlayColor wins — specifically in
the empty-children branch (the code using Children.count(children) and returning
View), change the style array to put blurStyle before overlay (e.g. [style,
blurStyle, overlay]) or ensure overlay.backgroundColor is assigned from the
overlayColor prop and used as the last item so overlayColor is not overwritten.
In `@src/ProgressiveBlurView.web.tsx`:
- Around line 107-122: getMaskGradient can produce inverted/overlapping gradient
stops when startOffset > 0.5; clamp the center offset to the range [0, 0.5]
before computing percentages and compute start/end from that clamped value
(e.g., let c = Math.min(Math.max(startOffset, 0), 0.5); start =
`${Math.round(c*100)}%`; end = `${100 - Math.round(c*100)}%`), update the
'blurredCenterClearTopAndBottom' branch to use those clamped values, and add a
safe default return for unknown ProgressiveBlurDirection values so the function
always returns a valid gradient string (reference: getMaskGradient and
ProgressiveBlurDirection).
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/BlurSwitch.web.tsxsrc/BlurView.web.tsxsrc/LiquidGlassContainer.web.tsxsrc/LiquidGlassView.web.tsxsrc/ProgressiveBlurView.web.tsxsrc/VibrancyView.web.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- src/LiquidGlassContainer.web.tsx
- src/LiquidGlassView.web.tsx
- src/VibrancyView.web.tsx
- src/BlurSwitch.web.tsx
|
Hey @sbaiahmed1, the components are working, but this error occurs when they are imported: Metro error: Importing native-only module "react-native/Libraries/Utilities/codegenNativeComponent" on web from: node_modules/@sbaiahmed1/react-native-blur/lib/module/ReactNativeBlurViewNativeComponent.ts
Import stack:
node_modules/@sbaiahmed1/react-native-blur/lib/module/ReactNativeBlurViewNativeComponent.ts
| import "react-native/Libraries/Utilities/codegenNativeComponent"
^ Importing react-native internals is not supported on web.
node_modules/@sbaiahmed1/react-native-blur/lib/module/index.js
| import "./ReactNativeBlurViewNativeComponent"
app/(tabs)/index.tsx
| import "@sbaiahmed1/react-native-blur"Note: They only work without this error when I import them directly from the lib folder. But even so, it still shows an error during import (it turns red): import { BlurView } from '@react-native-blur/lib/module/BlurView.web';I'm trying to figure out how to solve this: |
Hey @sbaiahmed1, I'm still trying fix this error. Basically, it occurs because |
Summary
Adds web platform support for all library components using CSS
backdrop-filter. This enables@sbaiahmed1/react-native-blurto work in React Native for Web projects without any additional configuration.Closes #79
Approach
Each component gets a
.web.tsxplatform-specific file that Metro/webpack automatically resolves when bundling for web. A dedicatedindex.web.tsxentry point re-exports web components and type-only re-exports from native component definitions (erased at compile time).Components implemented
backdrop-filter: blur(Npx)+ semi-transparentbackgroundColortint derived fromblurTypebackdrop-filter+ CSSmask-imagewithlinear-gradientfor directional blurbackdrop-filter: blur(40px) saturate(180%)with tint overlay for glass effectViewwithgapspacing (no native glass grouping API on web)SwitchcomponentBlurType mapping
All 21
BlurTypevalues are mapped to appropriatergba()background colours that approximate native iOSUIVisualEffectViewtints:xlight,light,*MaterialLight) → white-based overlays with increasing opacitydark,extraDark,*MaterialDark) → black-based overlays with increasing opacityProgressiveBlurView direction support
The
directionprop maps to CSSmask-imagegradients:blurredTopClearBottom→linear-gradient(to bottom, black, transparent)blurredBottomClearTop→linear-gradient(to top, black, transparent)blurredCenterClearTopAndBottom→ gradient with transparent edges and opaque centerThe
startOffsetprop controls where the gradient begins.Files added
src/BlurView.web.tsxsrc/VibrancyView.web.tsxsrc/ProgressiveBlurView.web.tsxsrc/LiquidGlassView.web.tsxsrc/LiquidGlassContainer.web.tsxsrc/BlurSwitch.web.tsxsrc/index.web.tsxBrowser support
CSS
backdrop-filteris supported in all modern browsers:-webkit-prefix)Notes
react-nativeand CSSblurAmountis clamped to 0–100 range matching the native behaviourSummary by CodeRabbit