@cornerkit/vue

Vue 3 components, composables, and directives for iOS-style squircle corners
1,491 13
Install
npm install @cornerkit/vue
Latest Version:1.1.0
Vue:3
License:MIT
Last Updated:Jul 19, 2026
Links: GitHub  ·  npm
Maintainer: bejarcode

@cornerkit/vue

Vue 3 components, composables, and directives for iOS-style squircle corners.

npm version Bundle Size License: MIT

Features

  • Three API styles: Component, Composable, and Directive
  • Full TypeScript support with IntelliSense
  • SSR-safe: Works with Nuxt 3 out of the box
  • Zero runtime dependencies: Only peer dependencies (Vue 3, @cornerkit/core)
  • Tiny bundle: < 2KB gzipped

Installation

npm install @cornerkit/vue @cornerkit/core
pnpm add @cornerkit/vue @cornerkit/core
yarn add @cornerkit/vue @cornerkit/core

Quick Start

Component (Recommended)

The simplest way to add squircle corners:

<script setup>
import { Squircle } from '@cornerkit/vue';
</script>

<template>
  <Squircle :radius="20" :smoothing="0.8">
    <button>iOS-style Button</button>
  </Squircle>
</template>

Composable

For more control or existing components:

<script setup>
import { useSquircle } from '@cornerkit/vue';

const { ref: cardRef, update, remove } = useSquircle({
  radius: 24,
  smoothing: 0.85
});
</script>

<template>
  <div ref="cardRef" class="card">
    Content with squircle corners
  </div>
</template>

Directive

For inline usage without wrapper:

<script setup>
import { vSquircle } from '@cornerkit/vue';
</script>

<template>
  <button v-squircle="{ radius: 20, smoothing: 0.8 }">
    Squircle Button
  </button>

  <!-- Shorthand (radius only) -->
  <div v-squircle="24" class="card">
    Quick squircle
  </div>
</template>

API Reference

<Squircle> Component

Declarative component for applying squircle corners.

Props
Prop Type Default Description
radius number 20 Corner radius in pixels
smoothing number 0.8 Curve smoothness (0-1)
border { width: number, color: string } - Optional border styling
tag keyof HTMLElementTagNameMap 'div' HTML element to render
Examples
<!-- Basic usage -->
<Squircle :radius="24">Content</Squircle>

<!-- As a button -->
<Squircle tag="button" :radius="16" @click="handleClick">
  Click me
</Squircle>

<!-- With border -->
<Squircle
  :radius="20"
  :smoothing="0.9"
  :border="{ width: 2, color: '#3b82f6' }"
>
  Card with border
</Squircle>

<!-- Access DOM element -->
<script setup>
const squircleRef = ref(null);
onMounted(() => console.log(squircleRef.value?.el));
</script>
<template>
  <Squircle ref="squircleRef">Content</Squircle>
</template>

useSquircle() Composable

Composable for imperative squircle control.

Signature
function useSquircle(options?: UseSquircleOptions): UseSquircleReturn;

interface UseSquircleOptions {
  radius?: number;
  smoothing?: number;
  border?: { width: number; color: string };
}

interface UseSquircleReturn {
  ref: Ref<HTMLElement | null>;
  update: (options: Partial<SquircleOptions>) => void;
  remove: () => void;
}
Examples
<script setup>
import { ref } from 'vue';
import { useSquircle } from '@cornerkit/vue';

// Basic usage
const { ref: cardRef } = useSquircle({ radius: 24 });

// With reactive options
const radius = ref(20);
const { ref: reactiveRef } = useSquircle({ radius: radius.value });

// Manual control
const { ref: controlRef, update, remove } = useSquircle({ radius: 20 });
function makeRounder() {
  update({ radius: 40 });
}

// Multiple instances
const { ref: ref1 } = useSquircle({ radius: 20 });
const { ref: ref2 } = useSquircle({ radius: 30 });
</script>

<template>
  <div ref="cardRef">Card 1</div>
  <div ref="reactiveRef">Card 2</div>
  <div ref="controlRef">Card 3</div>
  <button @click="makeRounder">Make Rounder</button>
</template>

v-squircle Directive

Custom directive for inline squircle application.

Value Types
type VSquircleValue = SquircleOptions | number;
Examples
<script setup>
import { vSquircle } from '@cornerkit/vue';
</script>

<template>
  <!-- Full config -->
  <div v-squircle="{ radius: 20, smoothing: 0.8 }">Full config</div>

  <!-- Number shorthand -->
  <div v-squircle="24">Radius only</div>

  <!-- With border -->
  <div v-squircle="{ radius: 20, border: { width: 2, color: 'blue' } }">
    With border
  </div>

  <!-- Reactive value -->
  <div v-squircle="config">Reactive</div>
</template>
Global Registration
// main.ts
import { createApp } from 'vue';
import { vSquircle } from '@cornerkit/vue';
import App from './App.vue';

const app = createApp(App);
app.directive('squircle', vSquircle);
app.mount('#app');

Borders & Hover Effects (v1.1.0+)

The border prop (component, composable, and directive) passes straight through to @cornerkit/core (v1.2+ API), so every border style works: solid, dashed, dotted, custom dash patterns, and gradients.

<template>
  <!-- Dashed border -->
  <Squircle :radius="20" :border="{ width: 2, color: '#6b7280', style: 'dashed' }">
    Drop zone
  </Squircle>

  <!-- Gradient border -->
  <Squircle
    :radius="24"
    :border="{
      width: 3,
      gradient: [
        { offset: '0%', color: '#3b82f6' },
        { offset: '100%', color: '#8b5cf6' },
      ],
    }"
  >
    Featured card
  </Squircle>

  <!-- Explicitly no border (overrides instance defaults / removes on update) -->
  <Squircle :radius="20" :border="null">Content</Squircle>
</template>

Hover effects need no props (core v1.3+): the border stroke and background resolve through CSS custom properties, so plain CSS restyles them:

.cta:hover {
  --ck-border-color: #8b5cf6;  /* border stroke on hover */
  --ck-background: #1e293b;    /* squircle background on hover */
}

TypeScript

Full TypeScript support with exported types:

import type {
  SquircleProps,
  SquircleExpose,
  SquircleOptions,
  SquircleBorderConfig,
  UseSquircleOptions,
  UseSquircleReturn,
  VSquircleValue,
  VSquircleDirective,
} from '@cornerkit/vue';

SSR / Nuxt 3

Works out of the box with Nuxt 3 and other SSR frameworks:

<!-- pages/index.vue -->
<script setup>
import { Squircle } from '@cornerkit/vue';
</script>

<template>
  <Squircle :radius="20">
    <NuxtLink to="/about">About</NuxtLink>
  </Squircle>
</template>

No special configuration needed - all DOM operations are deferred to onMounted.

Common Patterns

Card Component

<script setup>
import { Squircle } from '@cornerkit/vue';

defineProps<{
  title: string;
}>();
</script>

<template>
  <Squircle :radius="16" :smoothing="0.8" class="card">
    <h3>{{ title }}</h3>
    <slot />
  </Squircle>
</template>

<style scoped>
.card {
  padding: 1.5rem;
  background: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
</style>

Button with Hover Effect

<script setup>
import { ref, computed } from 'vue';
import { Squircle } from '@cornerkit/vue';

const isHovered = ref(false);
const radius = computed(() => isHovered.value ? 24 : 16);
</script>

<template>
  <Squircle
    tag="button"
    :radius="radius"
    :smoothing="0.85"
    @mouseenter="isHovered = true"
    @mouseleave="isHovered = false"
  >
    Hover me
  </Squircle>
</template>

List with v-for

<script setup>
import { Squircle } from '@cornerkit/vue';

const items = [
  { id: 1, name: 'Item 1' },
  { id: 2, name: 'Item 2' },
  { id: 3, name: 'Item 3' },
];
</script>

<template>
  <Squircle
    v-for="item in items"
    :key="item.id"
    :radius="12"
    class="list-item"
  >
    {{ item.name }}
  </Squircle>
</template>

Browser Support

Supports all browsers that Vue 3 supports. The underlying @cornerkit/core library uses progressive enhancement to choose the best rendering method.

Related Packages

License

MIT

Related Packages

@lisse/vue

Vue composable and component for smooth-cornered (squircle) elements

9,748 344
@alvarosabu/ui

UI Library for my personal projects

14,634 5
vue-haptics

Haptic feedback for Vue 3 that also works on iOS Safari, where the Vibration API...

712 1
vue-auth-href

Vue 3 directive and composable for downloading protected resources with authenti...

3,133 18
smooth-corners-vue

Smooth (continuous-curvature) corners for Vue 3. A directive, a composable and a...

305 0

Version History

Version Released Vue License
1.1.0 ^3.0.0 MIT
1.0.1 ^3.0.0 MIT
1.0.0 ^3.0.0 MIT