GrPromptDialog
Requests a short text input from the user in a dialog.
Overview
When to take it
- a single value is needed — the name of a folder, the reason for a refusal, a comment on a return: setting up a screen for the sake of one field is expensive;
- the value is checked —
rulesandrequiredwork before the confirmation, andfieldErrorshows the server’s refusal; - the text is long —
multilinewithautosizeturns the field into a text area; - the call comes from code —
useDialogService().prompt()returns a Promise with the value.
When to take something else
| Need | Take |
|---|---|
| Ask for consent rather than for a value | GrConfirmDialog |
| There are several fields | GrDialog + GrForm |
| The field lives on the screen itself | GrFormField + GrInput |
| Choose from ready options | GrDialog + GrSelect |
Playground controls come from the API, not from hand
The window opens above the page with the props set on the right.
0 changed· state is in the URL
<GrPromptDialog
title="Rename the report"
label="Report name"
v-model="value"
/>Examples 3 each with a live demo and its code
Renaming a report from its row
v-model:valueputs the current name in the field before the window opens — a rename almost always starts from it — andv-modelholds the window.confirmbrings the new value, not just the fact that the user agreed.Revenue by planUpdated TodayChurned accounts Q3Updated YesterdayOverdue invoicesUpdated 2 days agoA reason for a return
A reason does not fit one line:
multilineturns the field into a textarea,autosizegrows it with the answer, andmaxlengthwithshow-countnames the limit before it is hit — a scrollbar inside three rows would hide what has been written.Order #4820 · Wool cardigan, navy, LDelivered on 2 October · returnable until 30 OctoberDeliveredA project name the server has to accept
rulescheck the form of the name in the window, andfield-errorbrings the server’s refusal under the field. Withclose-on-confirm="false"the window closes only when the project exists;confirm-loadingandpersistentkeep it in place while the server answers. Try «q4-campaign».Projects · 2website-relaunchbilling-migration
API generated from the package · cannot drift
Props
| Prop | Type | default | Description |
|---|---|---|---|
title | string | undefined | undefined | The heading of the window, which is also its accessible name. Unset — taken from the locale. |
required | boolean | undefined | true | An empty value cannot be confirmed; the error shows after the first blur of the field or an attempt to confirm. `true` by default. |
size | "sm" | "md" | "lg" | "xl" | "full" | undefined | undefined | The width of the window on the `GrDialog` scale: from `sm` to `xl`, `full` — the whole screen. `md` by default. |
placeholder | string | undefined | undefined | Hint in an empty field. |
name | string | undefined | undefined | The name of the field. In the set not for company’s sake: password managers rely on it too, and for some of them saving a value without a name simply does not work. |
description | string | undefined | undefined | An explanation above the field. The `default` slot replaces it. |
label | string | undefined | undefined | The label of the field, which is also its accessible name. Unset — taken from the locale. |
closeOnBackdrop | boolean | undefined | true | Close on a click on the backdrop. `true` by default; with `persistent` it is switched off while a confirmation or a check of the `rules` is in progress. |
closeOnEsc | boolean | undefined | true | Close on Esc. `true` by default; with `persistent` it is switched off while a confirmation or a check of the `rules` is in progress. |
showHeader | boolean | undefined | true | Show the header with the heading and the close button. `true` by default. |
showCloseButton | boolean | undefined | true | The close button in the header. `true` by default; it stays with `persistent` too. |
headerConfig | GrDialogSectionConfig | undefined | undefined | The paddings and the line of the header: `paddingX`, `paddingY`, `bordered`. |
footerConfig | GrDialogSectionConfig | undefined | undefined | The paddings and the line of the footer with the buttons. |
bodyConfig | GrDialogSectionConfig | undefined | undefined | The paddings of the window body. `bordered` does not apply to the body. |
closeLabel | string | undefined | undefined | The a11y label of the close button (i18n). |
buttonSize | "xs" | "sm" | "md" | "lg" | undefined | undefined | The size of both footer buttons. Unset — the buttons take their size from `GrConfigProvider`. |
confirmText | string | undefined | undefined | The label of the confirm button. Unset — taken from the locale. |
cancelText | string | undefined | undefined | The label of the cancel button. Unset — taken from the locale. |
confirmVariant | GrButtonVariant | undefined | "primary" | The weight of the confirm button. `primary` by default. |
confirmTone |
| "primary" | The tone of the confirm button: `danger` — for an irreversible action. `primary` by default. |
error | ResponseErrorInfo | null | undefined | null | The structure of a server response error for showing as a common block in the body of the dialog (through `GrResponseErrorBanner`). `null` — the block is hidden. |
confirmLoading | boolean | undefined | false | The loading state of the Confirm button (an async `onConfirm` in flight). |
confirmDisabled | boolean | undefined | false | Forcibly disables the Confirm button. |
closeOnConfirm | boolean | undefined | true | Whether to close the dialog automatically on a click on Confirm. `true` by default. `false` hands the closing out (`useDialogService` is needed). |
persistent | boolean | undefined | false | A ban on closing by the "soft" ways (Esc, a click on the backdrop) while a confirmation or a check of the `rules` is in progress. The close button and "Cancel" stay: a window without a single exit is a trap. |
rows | number | undefined | undefined | The height of the multiline field in rows. |
rules | GrFormRule | GrFormRule[] | undefined | undefined | The rules for checking the value — the same as in `GrForm` (`required`, `type`, `min`/`max`/`len`, `pattern`, a `validator` of your own including an asynchronous one). They are run on blur (after the first touch) and on confirmation. |
autocomplete | string | undefined | undefined | What the person is being asked for — for the browser and the password manager (`current-password`, `new-password`, `one-time-code`, `off`). It is not derived from `inputType`: one and the same `password` has three different correct values, and the dialog does not know whether it is asking for an old password, a new one or a one-time code. The value is chosen by the consumer. |
inputmode |
| undefined | The software keyboard on mobile. |
maxlength | number | undefined | undefined | The limit on the length; with `showCount` a counter is drawn. |
showCount | boolean | undefined | false | A character counter under the field; with `maxlength` — in the form `len/maxlength`. |
requiredErrorText | string | undefined | undefined | The error text for an empty value with `required=true` (i18n). |
inputType | GrInputType | undefined | "text" | The type of the single-line field. It does not apply in the multiline mode. |
autocapitalize | "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | undefined | Auto-capitalisation on the software keyboard. The pair to `autocomplete="off"` for secrets typed by hand: a 2FA backup code is compared byte for byte, and the keyboard raises the first letter. |
spellcheck | boolean | undefined | undefined | Spell checking. The second half of the same pair. |
multiline | boolean | undefined | false | Multiline input: a `GrTextarea` is drawn instead of a `GrInput`. |
autosize | boolean | undefined | false | Automatic fitting of the height of the multiline field to the content. |
fieldError | string | null | undefined | null | An external error of the input field (server-side validation, for instance). It takes priority over the built-in check. `null`/`undefined` — there is no external error. |
modelValuerequiredv-model | boolean | — | Whether the window is open (`v-model`). Cancelling always closes it, confirming — with `closeOnConfirm`. |
valuerequiredv-model | string | — | The value of the field (`v-model:value`). The window does not reset it between openings. |
Slots
| Slot | Type | Description |
|---|---|---|
default | any | The content of the dialog instead of the text from the `description` prop. |
error | { error: ResponseErrorInfo | null; } | A breakdown of the error instead of the built-in banner. |
footer | any | The buttons of the dialog instead of the "cancel and confirm" pair. |
Events
| Event | Signature | Description |
|---|---|---|
update:modelValue | (event: "update:modelValue", value: boolean): void | — |
confirm | (event: "confirm", value: string): void | — |
cancel | (event: "cancel"): void | — |
update:value | (event: "update:value", value: string): void | — |
Types
Every exported type of the subpath, grouped by the file it lives in. Names, generics and bodies come from the package’s declaration files and cannot drift.
import type { GrPromptDialogProps, GrPromptDialogEmits } from '@feugene/granularity/components/GrPromptDialog'Filedist/types/components/GrPromptDialog/GrPromptDialog.vue.d.ts
interface GrPromptDialogProps {
modelValue: boolean;
value: string;
title?: string;
description?: string;
label?: string;
placeholder?: string;
closeOnBackdrop?: boolean;
closeOnEsc?: boolean;
showHeader?: boolean;
showCloseButton?: boolean;
size?: GrDialogSize;
headerConfig?: GrDialogSectionConfig;
footerConfig?: GrDialogSectionConfig;
bodyConfig?: GrDialogSectionConfig;
closeLabel?: string;
buttonSize?: GrButtonSize;
confirmText?: string;
cancelText?: string;
requiredErrorText?: string;
confirmVariant?: GrButtonVariant;
confirmTone?: GrButtonTone;
required?: boolean;
inputType?: GrInputType;
inputmode?: InputHTMLAttributes['inputmode'];
maxlength?: number;
showCount?: boolean;
autocomplete?: string;
name?: string;
autocapitalize?: 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
spellcheck?: boolean;
multiline?: boolean;
rows?: number;
autosize?: boolean;
rules?: GrFormRule | GrFormRule[];
error?: ResponseErrorInfo | null;
fieldError?: string | null;
confirmLoading?: boolean;
confirmDisabled?: boolean;
closeOnConfirm?: boolean;
persistent?: boolean;
}interface GrPromptDialogEmits {
(e: 'update:modelValue', value: boolean): void;
(e: 'update:value', value: string): void;
(e: 'confirm', value: string): void;
(e: 'cancel'): void;
}Filedist/types/components/GrPromptDialog/config.d.ts
const grPromptDialogConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrPromptDialog">;Accessibility
Keys
EscTab / Shift+Tab
Full contract of the package: docs/keyboard.md ↗
Usage from the library prose
The field
multiline switches GrInput to GrTextarea (rows, autosize) — the reason for a refusal or
a comment must not be assembled through a slot. For a single-line field there are inputType
(email, password, number, …) and inputmode. maxlength with showCount draws a counter;
it is already linked to the field through aria-describedby.
The field is obliged to introduce itself to the browser
autocomplete, name, autocapitalize and spellcheck reach the field in both branches — the
single-line and the multiline one. The default of all of them is the absence of the attribute: the
window makes nothing up.
dialog.prompt('Confirm the password', {
inputType: 'password',
autocomplete: 'current-password',
name: 'password',
})Without them a password manager does not recognise the field: 1Password, Safari and Chrome look at
autocomplete and at the name of the field, and the confirmation of a password has to be typed by
hand on every action.
autocomplete is not derived from inputType. One and the same password has three different
correct values — current-password, new-password, one-time-code — and the window does not
know which of them is right: it is used to ask for the old password, the new one and a one-time
code alike. A guess here would be a lie.
autocapitalize and spellcheck are the pair to autocomplete="off" for secrets that are typed
by hand. A 2FA backup code is compared byte for byte and is generated in mixed case: without
autocapitalize="off" a mobile keyboard raises the first letter.
dialog.prompt has the same four fields — a divergence between the declarative and the imperative
paths is guarded by the GrDialogService/__tests__/promptSurface.test.ts gate.
The field is not given an id: GrFormField generates it, and the field reads it from the
context. A literal id used to break exactly what it was written for — two open dialogs (an
ordinary one and one through the service) gave a duplicate DOM id, and <label for> led to
someone else’s input.
Checking the value
required (true by default) is a quick synchronous “not empty” check. It blocks the button and
does not go into the asynchronous engine.
Everything else is the rules prop with the same rules as in GrForm: type, min/max/len,
pattern, a validator of your own, an asynchronous one included. There is no third special case
of validation in the package — it is the same runFieldRules, and the messages are resolved by
the same createGrFormMessageResolver (both are public).
<GrPromptDialog
v-model="open"
v-model:value="email"
:rules="{ type: 'email', message: 'A work address is required' }"
/>The rules are run on blur (after the first touch) and on the confirmation. While a check is running, the button shows loading; the answer of a stale run is discarded — an asynchronous rule may come back after the value has already changed.
An error arrives from the outside as well: fieldError (the server-side validation of the field)
is stronger than the built-in checks, and error draws a general banner in the body of the
window.
The focus and the keyboard
On opening, the focus goes into the field rather than onto the panel of the window: the dialog
exists precisely for the sake of the input. That is done on the side of the content rather than
with the initialFocus prop of GrModal — the element is born inside the subtree of the dialog,
and returning it upwards through a prop closes the render into a loop.
Enter in a single-line field confirms. In the multiline mode Enter remains a line break, and
the confirmation is done with the button.
Props in this example