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. |
cancelVariant | GrButtonVariant | undefined | undefined | The weight of the cancel button. When not set — from `GrConfigProvider`, otherwise `outline`. A theme where cancelling is a quiet action next to the main one sets `ghost`. |
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;
cancelVariant?: GrButtonVariant;
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 weight of cancel
Cancel is outline, as in GrConfirmDialog; cancelVariant changes it and is configured in
GrConfigProvider together with the confirmation.
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