# rn-squircle

Complete squircle solution for React Native - smooth iOS-style corners for Views and Images.

Built on top of [expo-squircle-view](https://github.com/Malaa-tech/expo-squircle-view) by [@WadhahEssam](https://github.com/WadhahEssam) (Malaa-tech) with added `SquircleImage` component for proper image clipping.

## Credits

This library is built on top of the excellent work by **Malaa-tech**:
- **Original Library**: [expo-squircle-view](https://github.com/Malaa-tech/expo-squircle-view)
- **Original Author**: [@WadhahEssam](https://github.com/WadhahEssam)
- **License**: MIT

The original `expo-squircle-view` provides a native implementation for Figma corner smoothing (Squircle Shape) for React Native Expo apps. This library adds a `SquircleImage` component that uses `@react-native-masked-view/masked-view` to properly clip images with squircle corners.

## Why this library?

The original `expo-squircle-view` works perfectly for Views with background colors, but when you try to clip images using `overflow: 'hidden'`, native image components (like `expo-image`) don't respect the squircle mask. This library solves that problem by using MaskedView to properly clip images.

## Installation

```bash
npm install rn-squircle
# or
yarn add rn-squircle
# or
bun add rn-squircle
```

### Peer Dependencies

Make sure you have these installed:
```bash
npx expo install expo-image @react-native-masked-view/masked-view
```

> **Note**: This library requires a development build (`expo prebuild`). It won't work with Expo Go.

## Usage

### SquircleView

For views with background colors:

```tsx
import { SquircleView } from 'rn-squircle';

<SquircleView
  cornerSmoothing={100}
  preserveSmoothing={true}
  style={{
    width: 200,
    height: 200,
    backgroundColor: 'pink',
    borderRadius: 40,
  }}
>
  <Text>Squircle</Text>
</SquircleView>
```

### SquircleImage

For images with squircle clipping:

```tsx
import { SquircleImage } from 'rn-squircle';

<SquircleImage
  source={{ uri: 'https://example.com/image.jpg' }}
  style={{
    width: 200,
    height: 200,
    borderRadius: 40,
  }}
  cornerSmoothing={100}
  preserveSmoothing={true}
  contentFit="cover"
/>
```

### SquircleButton

For touchable squircle buttons:

```tsx
import { SquircleButton } from 'rn-squircle';

<SquircleButton
  cornerSmoothing={100}
  style={{
    width: 200,
    height: 50,
    backgroundColor: 'blue',
    borderRadius: 16,
  }}
  onPress={() => console.log('Pressed!')}
>
  <Text>Press me</Text>
</SquircleButton>
```

## API

### SquircleView

Re-exported from `expo-squircle-view`. See [original documentation](https://github.com/Malaa-tech/expo-squircle-view#readme).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `cornerSmoothing` | number | 100 | Controls smoothing (0 = no smoothing, 100 = max) |
| `preserveSmoothing` | boolean | false | Enhanced rounding for larger borderRadius |
| `borderRadius` | number | 0 | Border radius (can also be in style) |
| `backgroundColor` | ColorValue | - | Background color |
| `borderColor` | ColorValue | - | Border color |
| `borderWidth` | number | 0 | Border width |
| `style` | ViewStyle | - | Standard React Native ViewStyle |

### SquircleButton

Re-exported from `expo-squircle-view`. Same props as `SquircleView` plus `onPress` and other TouchableOpacity props.

### SquircleImage

All props from `expo-image` plus squircle-specific props:

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `cornerSmoothing` | number | 100 | Controls smoothing (0 = no smoothing, 100 = max) |
| `preserveSmoothing` | boolean | true | Enhanced rounding for larger borderRadius |
| `source` | ImageSource | - | Image source (same as expo-image) |
| `contentFit` | string | - | How image fits container |
| `placeholder` | object | - | Placeholder/blurhash |
| `transition` | number | - | Transition duration in ms |
| `style` | ImageStyle | - | Must include width, height, and borderRadius |

## How SquircleImage works

`SquircleImage` uses `@react-native-masked-view/masked-view` with a `SquircleView` as the mask element:

```tsx
<MaskedView
  maskElement={
    <SquircleView style={{ backgroundColor: 'black', borderRadius }} />
  }
>
  <Image />
</MaskedView>
```

The squircle shape acts as a cookie cutter - the image gets clipped to match the exact squircle contour.

## Platform Support

- iOS (requires `pod install`)
- Android

## License

MIT - See [LICENSE](./LICENSE)

## Acknowledgments

Massive thanks to [@WadhahEssam](https://github.com/WadhahEssam) and [Malaa-tech](https://github.com/Malaa-tech) for creating the original `expo-squircle-view` library. This library wouldn't exist without their excellent work on the native squircle implementation.
