MagicPie
MagicPie renders a percentage based value as SVG.
<template>
<div class="flex flex-col items-center gap-4">
<magic-pie
id="magic-pie-default-demo"
class="border-surface w-16 rounded-full border-2"
/>
<m-badge>{{ mappedPercentage }}</m-badge>
<div class="flex gap-2">
<m-button @click="start">Start</m-button>
<m-button @click="pause">Pause</m-button>
<m-button @click="stop">Stop</m-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { MButton, MBadge } from '@maas/mirror/vue'
import { useMagicPie } from '@maas/vue-equipment/plugins/MagicPie'
import { computed } from 'vue'
const {
percentage,
setPercentage,
interpolatePercentage,
cancelInterpolatePercentage,
} = useMagicPie('magic-pie-default-demo')
function start() {
if (percentage.value === 100) {
setPercentage(0)
}
interpolatePercentage({
value: 100,
duration: 2000,
})
}
function pause() {
cancelInterpolatePercentage()
}
function stop() {
if (percentage.value === 100) {
return
}
cancelInterpolatePercentage()
setPercentage(0)
}
const mappedPercentage = computed(() => {
return `${Math.round(percentage.value)}%`
})
</script>
<style>
[data-id='magic-pie-default-demo'] {
--magic-pie-background: var(--app-color-surface-high);
}
</style>Overview
Anatomy
<template>
<magic-pie id="your-pie-id" />
</template>
<script setup>
const { percentage } = useMagicPie('your-pie-id')
</script>Installation
CLI
Add @maas/vue-equipment to your dependencies.
pnpm install @maas/vue-equipmentnpm install @maas/vue-equipmentyarn add @maas/vue-equipmentbun install @maas/vue-equipmentVue
If you are using Vue, import and add MagicPiePlugin to your app.
import { createApp } from 'vue'
import { MagicPiePlugin } from '@maas/vue-equipment/plugins/MagicPie'
const app = createApp({})
app.use(MagicPiePlugin)Nuxt
The pie is available as a Nuxt module. In your Nuxt config file add @maas/vue-equipment/nuxt to your modules and add MagicPie to the plugins in your configuration.
export default defineNuxtConfig({
modules: ['@maas/vue-equipment/nuxt'],
vueEquipment: {
plugins: ['MagicPie'],
},
})Direct Import
If you prefer a more granular approach, the pie can also be directly imported into any Vue component.
<script setup>
import { MagicPie } from '@maas/vue-equipment/plugins/MagicPie'
</script>
<template>
<magic-pie id="your-pie-id" />
</template>Composable
In order to interact with the pie from anywhere within your app, we provide a useMagicPie composable. Import it directly when needed.
import { onMounted } from 'vue'
import { useMagicPie } from '@maas/vue-equipment/plugins/MagicPie'
const { setPercentage } = useMagicPie('your-pie-id')
onMounted(() => {
setPercentage(50)
})TIP
If you have installed the pie as a Nuxt module, the composable will be auto-imported and is automatically available in your Nuxt app.
API Reference
Props
The pie comes with a simple set of props. Only the id is required.
| Prop | Type | Required |
|---|---|---|
MaybeRef<string> | true | |
MagicPieOptions | false |
Options
| Option | Type | Default |
|---|---|---|
boolean | false |
CSS Variables
| Variable | Default |
|---|---|
--magic-pie-background | transparent |
--magic-pie-foreground | currentColor |
Examples
Flip
<template>
<div class="flex flex-col items-center gap-4">
<magic-pie
id="magic-pie-flip-demo"
class="border-surface w-16 rounded-full border-2"
:options="{ flip }"
/>
<m-badge>{{ mappedPercentage }}</m-badge>
<div class="flex gap-2">
<m-button @click="start">Start</m-button>
<m-button @click="pause">Pause</m-button>
<m-button @click="stop">Stop</m-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, watch } from 'vue'
import { MButton, MBadge } from '@maas/mirror/vue'
import { useMagicPie } from '@maas/vue-equipment/plugins/MagicPie'
const flip = ref(false)
const {
percentage,
setPercentage,
interpolatePercentage,
cancelInterpolatePercentage,
} = useMagicPie('magic-pie-flip-demo')
function start() {
interpolatePercentage({
value: 100,
duration: 2000,
})
}
function pause() {
cancelInterpolatePercentage()
}
function stop() {
if (percentage.value === 100) {
return
}
cancelInterpolatePercentage()
setPercentage(0)
}
const mappedPercentage = computed(() => {
return `${Math.round(percentage.value)}%`
})
watch(
() => percentage.value,
(value) => {
if (value === 100) {
setPercentage(0)
flip.value = !flip.value
start()
}
}
)
</script>
<style>
[data-id='magic-pie-flip-demo'] {
--magic-pie-background: var(--app-color-surface-high);
}
</style>Errors
| Source | Error Code | Message |
|---|---|---|
MagicPie | missing_points | At least two points are required to generate a path |
MagicPie | invalid_percentage | percentage needs to be between 0 and 100 |