Skip to content

Feedback Form

A Neo-Brutalist feedback form featuring a title, description, and complete form fields (name, email, subject, message) with a submit button.

Demo

Preview

发送反馈

我们很乐意听取您的意见

加载与成功状态

填写表单后点击提交,先进入 loading 态,请求完成后切换为成功状态。

发送反馈

我们很乐意听取您的意见

预览成功状态

Installation

pnpm dlx brutx-vue@latest add feedback-form

Usage

vue
<script setup>
import FeedbackForm from '@/components/ui/feedback-form/FeedbackForm.vue'

function handleSubmit(payload) {
    console.log('Feedback:', payload)
    // payload: { name, email, subject, message }
}
</script>

<template>
    <FeedbackForm
        title="Send Feedback"
        description="We'd love to hear from you."
        submit-text="Submit"
        @submit="handleSubmit"
    />
</template>

Custom Text

vue
<script setup>
import FeedbackForm from '@/components/ui/feedback-form/FeedbackForm.vue'
</script>

<template>
    <FeedbackForm
        title="Contact Us"
        description="Have a question? Reach out to our team."
        submit-text="Send Message"
        @submit="handleContact"
    />
</template>

Loading State

Set loading to true to put the submit button in a loading state with a spinner, preventing duplicate submissions during this period. The submit event still fires normally; the caller should set loading back to false after the async request completes.

vue
<script setup>
import { ref } from 'vue'
import FeedbackForm from '@/components/ui/feedback-form/FeedbackForm.vue'

const loading = ref(false)

async function handleSubmit(payload) {
    loading.value = true
    await sendFeedback(payload)
    loading.value = false
}
</script>

<template>
    <FeedbackForm :loading="loading" @submit="handleSubmit" />
</template>

Success State

Set success to true to replace the form with the Result success state, displaying a success title, description, and confirm button. Clicking the confirm button triggers the success-confirm event; the caller decides the follow-up behavior (e.g., resetting the form, navigating away).

vue
<script setup>
import { ref } from 'vue'
import FeedbackForm from '@/components/ui/feedback-form/FeedbackForm.vue'

const loading = ref(false)
const success = ref(false)

async function handleSubmit(payload) {
    loading.value = true
    await sendFeedback(payload)
    loading.value = false
    success.value = true
}

function handleSuccessConfirm() {
    success.value = false
}
</script>

<template>
    <FeedbackForm
        :loading="loading"
        :success="success"
        success-title="Feedback Received"
        success-description="Thank you for your feedback. We will process it as soon as possible."
        success-confirm-text="Submit Another"
        @submit="handleSubmit"
        @success-confirm="handleSuccessConfirm"
    />
</template>

Props

PropTypeDefaultDescription
titlestringlocale: feedbackForm.defaultTitleForm title
descriptionstringlocale: feedbackForm.defaultDescriptionForm description text
submitTextstringlocale: feedbackForm.defaultSubmitTextSubmit button text
loadingbooleanfalseWhether in loading state
successbooleanfalseWhether to show the success card
successTitlestringlocale: feedbackForm.successTitleSuccess state title
successDescriptionstringlocale: feedbackForm.successDescriptionSuccess state description text
successConfirmTextstringlocale: feedbackForm.successConfirmTextSuccess state confirm button text
iconSizeIconSize'default'Icon size
classstringCustom CSS class

Events

EventParametersDescription
submit[{ name: string; email: string; subject: string; message: string }]Emitted on form submission, carrying the form data
success-confirm[]Emitted when the success card confirm button is clicked

Slots

SlotScopeDescription
headerReplace/extend the block header
defaultReplace the block main content (including the form)
footerReplace/extend the block footer

Accessibility

  • All form fields use semantic <label> associations, ensuring screen readers can correctly identify them.
  • The submit button is disabled in the loading state to prevent duplicate submissions.
  • The success card provides a confirm button with keyboard navigation and focus management support.

Brute force builds.