FTxDialog
A flexible wrapper component for Quasar's QDialog with customizable header, footer, and content options. Supports both standalone mode (v-model) and store mode (useDialogStore).
Key Features
- ✅ Standalone mode (v-model) or store mode (useDialogStore)
- ✅ Customizable header with icon and subtitle
- ✅ Scrollable content area with auto-height
- ✅ Custom slots for complete control
- ✅ All Quasar dialog props pass through automatically
- ✅ No default padding (matches original behavior)
Props
| Prop | Type | Default | Description |
|---|---|---|---|
dialog | String | null | Dialog name (for store mode) - optional if using v-model |
modelValue | Boolean | false | Dialog visibility (for standalone mode) |
title | String | '' | Dialog title shown in header |
subtitle | String | '' | Subtitle shown below title |
headerIcon | String | '' | Icon shown in header before title |
headerIconColor | String | 'primary' | Header icon color |
headerIconSize | String | 'md' | Header icon size |
showHeader | Boolean | true | Show header with title and close button |
showCloseButton | Boolean | true | Show close button in header |
showFooter | Boolean | true | Show footer with action buttons |
showResetButton | Boolean | true | Show reset button in footer |
showSaveButton | Boolean | true | Show save button in footer |
resetLabel | String | 'Cancel' | Reset button label |
resetIcon | String | '' | Reset button icon |
resetLabelColor | String | 'deep-purple-1' | Reset button color |
resetLabelTextColor | String | 'primary' | Reset button text color |
resetLoading | Boolean | false | Reset button loading state |
saveLabel | String | 'Save' | Save button label |
saveIcon | String | '' | Save button icon |
saveBtnColor | String | 'primary' | Save button color |
saveTextColor | String | '' | Save button text color |
saveDisabled | Boolean | false | Disable save button |
resetDisabled | Boolean | false | Disable reset button |
submitting | Boolean | false | Show loading state on save button |
size | String | '' | Dialog size class |
cancelToCloseAll | Boolean | true | If true, cancel button closes all dialogs (store mode only) |
confirmBeforeClose | Boolean | false | If true, emits reset event before closing |
style | String | Object | '' | Custom style for dialog card |
contentClass | String | '' | Additional CSS classes for content |
contentStyle | String | Object | '' | Inline styles for content |
autoHeight | Boolean | false | Enable auto-height layout (flex with scrollable content) |
maxHeight | String | Number | null | Max height for content area (when autoHeight is true) |
contentPadding | String | '' | Content padding class (e.g., 'q-pa-md') - empty by default |
footerAlign | String | 'between' | Footer button alignment: 'left', 'right', 'between' |
closeButtonAriaLabel | String | 'Close dialog' | Aria label for close button |
saveButtonAriaLabel | String | 'Save' | Aria label for save button |
resetButtonAriaLabel | String | 'Cancel' | Aria label for reset button |
Quasar Dialog Props
All Quasar dialog props pass through automatically via $attrs:
persistent,maximized,positiontransition-show,transition-hideno-esc-dismiss,no-backdrop-dismiss,no-route-dismissauto-close- And all other Quasar QDialog props
Events
update:modelValue- Emitted when dialog visibility changes (standalone mode)submit- Emitted when save button is clickedreset- Emitted when reset button is clickedhide- Emitted when dialog is hiddenshow- Emitted when dialog is shown
Slots
default- Dialog contentheader- Custom header (receives{ close, title, icon })footer- Custom footer (receives{ submit, reset, submitting })close-button- Custom close button (receives{ close })
Usage Examples
Standalone Mode (v-model)
vue
<template>
<div>
<q-btn label="Open Dialog" @click="showDialog = true" />
<FTxDialog
v-model="showDialog"
title="Example Dialog"
subtitle="This is a subtitle"
header-icon="info"
:show-header="true"
:show-footer="true"
reset-label="Cancel"
save-label="Save"
persistent
position="top"
@submit="handleSubmit"
@reset="handleReset"
>
<q-card-section>
<q-input v-model="formData.name" label="Name" />
</q-card-section>
</FTxDialog>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { FTxDialog } from '@ftx/ui';
const showDialog = ref(false);
const formData = ref({ name: '' });
function handleSubmit() {
console.log('Submitted:', formData.value);
showDialog.value = false;
}
function handleReset() {
formData.value = { name: '' };
showDialog.value = false;
}
</script>Store Mode (useDialogStore)
vue
<template>
<div>
<q-btn label="Open Dialog" @click="openDialog" />
<FTxDialog
dialog="example-dialog"
title="Example Dialog"
:show-header="true"
:show-footer="true"
reset-label="Cancel"
save-label="Save"
@submit="handleSubmit"
@reset="handleReset"
>
<q-card-section>
<q-input v-model="formData.name" label="Name" />
</q-card-section>
</FTxDialog>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { FTxDialog, useDialogStore } from '@ftx/ui';
const dialogStore = useDialogStore();
const formData = ref({ name: '' });
async function openDialog() {
await dialogStore.updateDialog({
name: 'example-dialog',
value: true,
});
}
function handleSubmit() {
console.log('Submitted:', formData.value);
dialogStore.closeDialog('example-dialog');
}
function handleReset() {
formData.value = { name: '' };
dialogStore.closeDialog('example-dialog');
}
</script>Scrollable Content
vue
<FTxDialog
v-model="showDialog"
title="Long Content Dialog"
auto-height
max-height="500px"
content-padding="q-pa-md"
>
<q-card-section>
<!-- Long scrollable content -->
</q-card-section>
</FTxDialog>Custom Header
vue
<FTxDialog v-model="showDialog" title="Custom Header">
<template #header="{ close, title }">
<q-card-section class="dialog-header bg-primary text-white">
<div class="row items-center justify-between">
<div class="text-h6">{{ title }}</div>
<q-btn flat round dense icon="close" @click="close" />
</div>
</q-card-section>
</template>
<q-card-section>Content here</q-card-section>
</FTxDialog>Custom Footer
vue
<FTxDialog v-model="showDialog" title="Custom Footer">
<q-card-section>Content here</q-card-section>
<template #footer="{ submit, reset }">
<q-card-section class="row justify-end q-gutter-sm q-pa-md">
<q-btn label="Cancel" flat @click="reset" />
<q-btn label="Save Draft" color="grey" @click="() => console.log('Draft')" />
<q-btn label="Publish" color="primary" @click="submit" />
</q-card-section>
</template>
</FTxDialog>Notes
- Standalone mode: Use
v-modelfor dialog state (doesn't require useDialogStore) - Store mode: Use
dialogprop withuseDialogStorefor centralized dialog management - No default padding: Content has no padding by default (matches original behavior). Add
content-padding="q-pa-md"if needed. - Quasar props: All Quasar dialog props pass through automatically - no need to define them explicitly