react-native-lisse
v0.2.0
Published
React Native components and hooks for Lisse smooth corners
Maintainers
Readme
react-native-lisse
React Native components powered by Lisse. The package uses the DOM-free @lisse/core/path entrypoint, so its squircle, arc, superellipse, and clothoid paths match the web packages. On iOS, native children are clipped with an exact CAShapeLayer path. Android and unlinked iOS builds use the SVG mask fallback.
Install
npm install react-native-lisse @react-native-masked-view/masked-view react-native-svg
npx pod-installThe pod step is required for bare iOS projects. Expo projects can use the usual Expo-compatible installs for the two native peer dependencies.
npm install react-native-lisse
npx expo install @react-native-masked-view/masked-view react-native-svgComponent
import { Text } from "react-native";
import { SmoothCorners } from "react-native-lisse";
export function Card() {
return (
<SmoothCorners
corners={{ radius: 24, smoothing: 0.6 }}
innerBorder={{ width: 1, color: "#fff", opacity: 0.2 }}
shadow={{
offsetX: 0,
offsetY: 8,
blur: 16,
spread: 0,
color: "#000",
opacity: 0.18,
}}
style={{ width: 300, padding: 24, backgroundColor: "#2563eb" }}
>
<Text style={{ color: "#fff" }}>Hello, squircle</Text>
</SmoothCorners>
);
}style keeps normal React Native layout behavior. The renderer moves backgroundColor into the masked layer and splits outer layout styles from inner content styles, so padding and intrinsic content height continue to work. Uniform borderWidth, borderColor, and supported native shadow objects are converted when autoEffects is enabled. With autoEffects={false}, native border and shadow styles stay on the outer View; those platform effects use the native rounded-rectangle silhouette and may not match the Lisse curve exactly.
The component supports per-corner configuration, all four Lisse curve families, inner, middle, and outer borders, gradient borders, the six Lisse border styles, drop shadows, inner shadows, responsive layout, and forwarded View refs.
The default renderStrategy="auto" uses the native clip view on iOS when CocoaPods has linked it. Use renderStrategy="mask" to force the previous cross-platform renderer during migration or visual comparisons. renderStrategy="native" requests the native renderer but still falls back safely when it is unavailable.
Hook
React Native has no DOM element that a hook can mutate with clip-path, so the hook returns measured geometry instead:
const geometry = useSmoothCorners(
{ radius: 24, smoothing: 0.6 },
{ initialSize: { width: 200, height: 120 } },
);
return <View onLayout={geometry.onLayout}>{geometry.path}</View>;The result contains width, height, path, ready, and onLayout. Use it with react-native-svg, Skia, or another custom renderer.
Platform notes
- iOS and Android are supported. React Native Web should keep using
@lisse/react, because@react-native-masked-view/masked-viewdoes not support web. - iOS uses a
CAShapeLayermask for the content clip while SVG remains responsible for borders and shadows. This removes one MaskedView and SVG mask subtree from every ordinary smooth-corner container without approximating the Lisse curve. - Android defaults to
androidRenderingMode="software", because the path changes when layout changes. A truly static card can opt into"hardware"for cheaper compositing. - Animated width, height, radius, or smoothing values need ordinary React updates so the JavaScript path can be regenerated. Reanimated worklet-only styles cannot update this component's SVG path by themselves.
asandasChildare DOM composition APIs and are intentionally absent. WrapSmoothCornersinPressable, or put aPressableinside it.
Local verification
The automated suite covers core-path parity, layout measurement, style and effect extraction, edge-case geometry, component rendering, type declarations, and package exports.
npm install
npm run check
npm pack --dry-run