O componente PricingPlan oferece uma maneira flexível de exibir um plano de preços com conteúdo personalizável, incluindo título, descrição, preço, recursos, etc.
Use a prop title para definir o título do PricingPlan.
<template>
<NPricingPlan title="Solo" class="w-96" />
</template>
Use a prop description para definir a descrição do PricingPlan.
<template>
<NPricingPlan title="Solo" description="For bootstrappers and indie hackers." />
</template>
Use a prop badge para exibir um Badge ao lado do título do PricingPlan.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
badge="Most popular"
/>
</template>
Você pode passar qualquer propriedade do componente Badge para personalizá-lo.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
:badge="{
label: 'Most popular',
color: 'neutral',
variant: 'solid'
}"
/>
</template>
Use a prop price para definir o preço do PricingPlan.
<template>
<NPricingPlan title="Solo" description="For bootstrappers and indie hackers." price="$249" />
</template>
Use a prop discount para definir um preço com desconto que será exibido ao lado do preço original (que aparecerá riscado).
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
discount="$199"
/>
</template>
Use as props billing-cycle e/ou billing-period para exibir as informações de cobrança do PricingPlan.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$9"
billing-cycle="/month"
billing-period="billed annually"
/>
</template>
Use a prop features como um array de strings para exibir uma lista de recursos no PricingPlan:
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="[
'One developer',
'Unlimited projects',
'Access to GitHub repository',
'Unlimited patch & minor updates',
'Lifetime access'
]"
/>
</template>
Você também pode passar um array de objetos com as seguintes propriedades:
title: stringicon?: string<script setup lang="ts">
import type { PricingPlanFeature } from '@nitro/ui'
const features = ref<PricingPlanFeature[]>([
{
title: 'One developer',
icon: 'i-lucide-user'
},
{
title: 'Unlimited projects',
icon: 'i-lucide-infinity'
},
{
title: 'Access to GitHub repository',
icon: 'i-lucide-github'
},
{
title: 'Unlimited patch & minor updates',
icon: 'i-lucide-refresh-cw'
},
{
title: 'Lifetime access',
icon: 'i-lucide-clock'
}
])
</script>
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="features"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { PricingPlanFeature } from '@nitro/ui'
const features = ref<PricingPlanFeature[]>([
{
title: 'One developer',
icon: 'i-lucide-user'
},
{
title: 'Unlimited projects',
icon: 'i-lucide-infinity'
},
{
title: 'Access to GitHub repository',
icon: 'i-lucide-github'
},
{
title: 'Unlimited patch & minor updates',
icon: 'i-lucide-refresh-cw'
},
{
title: 'Lifetime access',
icon: 'i-lucide-clock'
}
])
</script>
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="features"
/>
</template>
Use a prop button com qualquer propriedade do componente Button para exibir um botão na parte inferior do PricingPlan.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="[
'One developer',
'Unlimited projects',
'Access to GitHub repository',
'Unlimited patch & minor updates',
'Lifetime access'
]"
:button="{
label: 'Buy now'
}"
/>
</template>
onClick para adicionar um handler de clique que dispara a compra do plano.Use a prop variant para alterar a variante do PricingPlan.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="[
'One developer',
'Unlimited projects',
'Access to GitHub repository',
'Unlimited patch & minor updates',
'Lifetime access'
]"
:button="{
label: 'Buy now'
}"
variant="subtle"
/>
</template>
Use a prop orientation para alterar a orientação do PricingPlan. O padrão é vertical.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="[
'One developer',
'Unlimited projects',
'Access to GitHub repository',
'Lifetime access'
]"
:button="{
label: 'Buy now'
}"
orientation="horizontal"
variant="outline"
/>
</template>
Use a prop tagline para exibir um texto de slogan acima do preço.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="[
'One developer',
'Unlimited projects',
'Access to GitHub repository',
'Lifetime access'
]"
:button="{
label: 'Buy now'
}"
orientation="horizontal"
tagline="Pay once, own it forever"
/>
</template>
Use a prop terms para exibir os termos abaixo do preço.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="[
'One developer',
'Unlimited projects',
'Access to GitHub repository',
'Lifetime access'
]"
:button="{
label: 'Buy now'
}"
orientation="horizontal"
tagline="Pay once, own it forever"
terms="Invoices and receipts available."
/>
</template>
Use a prop highlight para exibir uma borda destacada ao redor do PricingPlan.
<template>
<NPricingPlan
title="Solo"
description="For bootstrappers and indie hackers."
price="$249"
:features="[
'One developer',
'Unlimited projects',
'Access to GitHub repository',
'Unlimited patch & minor updates',
'Lifetime access'
]"
:button="{
label: 'Buy now'
}"
highlight
/>
</template>
Use a prop scale para tornar um PricingPlan maior que os outros.
scale do PricingPlans para ver como funciona, já que é difícil demonstrar isoladamente.| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
title | string | |
description | string | |
badge | string | BadgePropsDisplay a badge next to the title.
Can be a string or an object.
| |
billingCycle | stringThe unit price period that appears next to the price. Typically used to show the recurring interval. | |
billingPeriod | stringAdditional billing context that appears above the billing cycle. Typically used to show the actual billing frequency. | |
price | stringThe current price of the plan.
When used with | |
discount | stringThe discounted price of the plan.
When provided, the | |
features | string[] | PricingPlanFeature[]Display a list of features under the price. Can be an array of strings or an array of objects. | |
button | ButtonPropsDisplay a buy button at the bottom.
| |
tagline | stringDisplay a tagline highlighting the pricing value proposition. | |
terms | stringDisplay terms at the bottom. | |
orientation | 'vertical' | "vertical" | "horizontal"The orientation of the pricing plan. |
variant | 'outline' | "soft" | "solid" | "outline" | "subtle" |
highlight | boolean Display a ring around the pricing plan to highlight it. | |
scale | boolean Enlarge the plan to make it more prominent. | |
ui | { root?: SlotClass; header?: SlotClass; body?: SlotClass; footer?: SlotClass; titleWrapper?: SlotClass; title?: SlotClass; description?: SlotClass; priceWrapper?: SlotClass; price?: SlotClass; discount?: SlotClass; billing?: SlotClass; billingPeriod?: SlotClass; billingCycle?: SlotClass; features?: SlotClass; feature?: SlotClass; featureIcon?: SlotClass; featureTitle?: SlotClass; badge?: SlotClass; button?: SlotClass; tagline?: SlotClass; terms?: SlotClass; } |
| Slot | Type |
|---|---|
badge | { ui: object; } |
title | {} |
description | {} |
price | {} |
discount | {} |
billing | { ui: object; } |
features | {} |
button | { ui: object; } |
header | {} |
body | {} |
footer | {} |
tagline | {} |
terms | {} |
export default defineAppConfig({
ui: {
pricingPlan: {
slots: {
root: 'relative grid rounded-lg p-6 lg:p-8 xl:p-10 gap-6',
header: '',
body: 'flex flex-col min-w-0',
footer: 'flex flex-col gap-6 items-center',
titleWrapper: 'flex items-center gap-3',
title: 'text-highlighted truncate text-2xl sm:text-3xl text-pretty font-semibold',
description: 'text-muted text-base text-pretty mt-2',
priceWrapper: 'flex items-center gap-1',
price: 'text-highlighted text-3xl sm:text-4xl font-semibold',
discount: 'text-muted line-through text-xl sm:text-2xl',
billing: 'flex flex-col justify-between min-w-0',
billingPeriod: 'text-toned truncate text-xs font-medium',
billingCycle: 'text-muted truncate text-xs font-medium',
features: 'flex flex-col gap-3 flex-1 mt-6 grow-0',
feature: 'flex items-center gap-2 min-w-0',
featureIcon: 'size-5 shrink-0 text-primary',
featureTitle: 'text-muted text-sm truncate',
badge: '',
button: '',
tagline: 'text-base font-semibold text-default',
terms: 'text-xs/5 text-muted text-center text-balance'
},
variants: {
orientation: {
horizontal: {
root: 'grid-cols-1 lg:grid-cols-3 justify-between divide-y lg:divide-y-0 lg:divide-x divide-default',
body: 'lg:col-span-2 pb-6 lg:pb-0 lg:pr-6 justify-center',
footer: 'lg:justify-center lg:items-center lg:p-6 lg:max-w-xs lg:w-full lg:mx-auto',
features: 'lg:grid lg:grid-cols-2 lg:mt-12'
},
vertical: {
footer: 'justify-end',
priceWrapper: 'mt-6'
}
},
variant: {
solid: {
root: 'bg-inverted',
title: 'text-inverted',
description: 'text-dimmed',
price: 'text-inverted',
discount: 'text-dimmed',
billingCycle: 'text-dimmed',
billingPeriod: 'text-dimmed',
featureTitle: 'text-dimmed'
},
outline: {
root: 'bg-default ring ring-default'
},
soft: {
root: 'bg-elevated/50'
},
subtle: {
root: 'bg-elevated/50 ring ring-default'
}
},
highlight: {
true: {
root: 'ring-2 ring-inset ring-primary'
}
},
scale: {
true: {
root: 'lg:scale-[1.1] lg:z-1'
}
}
},
compoundVariants: [
{
orientation: 'horizontal',
variant: 'soft',
class: {
root: 'divide-accented'
}
},
{
orientation: 'horizontal',
variant: 'subtle',
class: {
root: 'divide-accented'
}
}
],
defaultVariants: {
variant: 'outline'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
pricingPlan: {
slots: {
root: 'relative grid rounded-lg p-6 lg:p-8 xl:p-10 gap-6',
header: '',
body: 'flex flex-col min-w-0',
footer: 'flex flex-col gap-6 items-center',
titleWrapper: 'flex items-center gap-3',
title: 'text-highlighted truncate text-2xl sm:text-3xl text-pretty font-semibold',
description: 'text-muted text-base text-pretty mt-2',
priceWrapper: 'flex items-center gap-1',
price: 'text-highlighted text-3xl sm:text-4xl font-semibold',
discount: 'text-muted line-through text-xl sm:text-2xl',
billing: 'flex flex-col justify-between min-w-0',
billingPeriod: 'text-toned truncate text-xs font-medium',
billingCycle: 'text-muted truncate text-xs font-medium',
features: 'flex flex-col gap-3 flex-1 mt-6 grow-0',
feature: 'flex items-center gap-2 min-w-0',
featureIcon: 'size-5 shrink-0 text-primary',
featureTitle: 'text-muted text-sm truncate',
badge: '',
button: '',
tagline: 'text-base font-semibold text-default',
terms: 'text-xs/5 text-muted text-center text-balance'
},
variants: {
orientation: {
horizontal: {
root: 'grid-cols-1 lg:grid-cols-3 justify-between divide-y lg:divide-y-0 lg:divide-x divide-default',
body: 'lg:col-span-2 pb-6 lg:pb-0 lg:pr-6 justify-center',
footer: 'lg:justify-center lg:items-center lg:p-6 lg:max-w-xs lg:w-full lg:mx-auto',
features: 'lg:grid lg:grid-cols-2 lg:mt-12'
},
vertical: {
footer: 'justify-end',
priceWrapper: 'mt-6'
}
},
variant: {
solid: {
root: 'bg-inverted',
title: 'text-inverted',
description: 'text-dimmed',
price: 'text-inverted',
discount: 'text-dimmed',
billingCycle: 'text-dimmed',
billingPeriod: 'text-dimmed',
featureTitle: 'text-dimmed'
},
outline: {
root: 'bg-default ring ring-default'
},
soft: {
root: 'bg-elevated/50'
},
subtle: {
root: 'bg-elevated/50 ring ring-default'
}
},
highlight: {
true: {
root: 'ring-2 ring-inset ring-primary'
}
},
scale: {
true: {
root: 'lg:scale-[1.1] lg:z-1'
}
}
},
compoundVariants: [
{
orientation: 'horizontal',
variant: 'soft',
class: {
root: 'divide-accented'
}
},
{
orientation: 'horizontal',
variant: 'subtle',
class: {
root: 'divide-accented'
}
}
],
defaultVariants: {
variant: 'outline'
}
}
}
})
]
})