Dialog Pesan
Dialog Pesan
Wails menyediakan dialog pesan native dengan tampilan sesuai platform: dialog info, peringatan, error, dan pertanyaan dengan judul, pesan, dan tombol yang dapat disesuaikan. API sederhana, perilaku native, accessible secara default.
Membuat Dialog
Dialog pesan diakses melalui app.Dialog manager:
app.Dialog.Info()
app.Dialog.Question()
app.Dialog.Warning()
app.Dialog.Error()Semua metode mengembalikan *MessageDialog that can be configured using method chaining.
Dialog Informasi
Tampilkan pesan informasi:
app.Dialog.Info().
SetTitle("Success").
SetMessage("File saved successfully!").
Show()Kasus penggunaans:
- Success confirmations
- Completion notices
- Informational messages
- Status updates
Example - Save confirmation:
func saveFile(app *application.App, path string, data []byte) error {
if err := os.WriteFile(path, data, 0644); err != nil {
return err
}
app.Dialog.Info().
SetTitle("File Saved").
SetMessage(fmt.Sprintf("Saved to %s", filepath.Base(path))).
Show()
return nil
}Dialog Peringatan
Tampilkan peringatan:
app.Dialog.Warning().
SetTitle("Warning").
SetMessage("This action cannot be undone.").
Show()Kasus penggunaans:
- Non-critical warnings
- Deprecation notices
- Caution messages
- Potential issues
Example - Disk space warning:
func checkDiskSpace(app *application.App) {
available := getDiskSpace()
if available < 100*1024*1024 { // Less than 100MB
app.Dialog.Warning().
SetTitle("Low Disk Space").
SetMessage(fmt.Sprintf("Only %d MB available.", available/(1024*1024))).
Show()
}
}Dialog Error
Tampilkan error:
app.Dialog.Error().
SetTitle("Error").
SetMessage("Failed to connect to server.").
Show()Kasus penggunaans:
- Error messages
- Failure notifications
- Exception handling
- Critical issues
Example - Network error:
func fetchData(app *application.App, url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
app.Dialog.Error().
SetTitle("Network Error").
SetMessage(fmt.Sprintf("Failed to connect: %v", err)).
Show()
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}Dialog Pertanyaan
Ajukan pertanyaan kepada pengguna dan tangani respons melalui callback tombol:
dialog := app.Dialog.Question().
SetTitle("Confirm").
SetMessage("Save changes before closing?")
save := dialog.AddButton("Save")
save.OnClick(func() {
saveChanges()
})
dontSave := dialog.AddButton("Don't Save")
dontSave.OnClick(func() {
// Continue without saving
})
cancel := dialog.AddButton("Cancel")
cancel.OnClick(func() {
// Don't close
})
dialog.SetDefaultButton(save)
dialog.SetCancelButton(cancel)
dialog.Show()Kasus penggunaans:
- Confirm actions
- Yes/No questions
- Multiple choice
- User decisions
Example - Unsaved changes:
func closeDocument(app *application.App) {
if !hasUnsavedChanges() {
doClose()
return
}
dialog := app.Dialog.Question().
SetTitle("Unsaved Changes").
SetMessage("Do you want to save your changes?")
save := dialog.AddButton("Save")
save.OnClick(func() {
if saveDocument() {
doClose()
}
})
dontSave := dialog.AddButton("Don't Save")
dontSave.OnClick(func() {
doClose()
})
cancel := dialog.AddButton("Cancel")
// Cancel button has no callback - just closes the dialog
dialog.SetDefaultButton(save)
dialog.SetCancelButton(cancel)
dialog.Show()
}Opsi Dialog
Judul dan Pesan
dialog := app.Dialog.Info().
SetTitle("Operation Complete").
SetMessage("All files have been processed successfully.")Best practices:
- Title: Short, descriptive (2-5 words)
- Message: Clear, specific, actionable
- Avoid jargon: Use plain language
Tombol
Satu tombol (Info/Peringatan/Error):
Info, warning, and error dialogs display a default “OK” button:
app.Dialog.Info().
SetMessage("Done!").
Show()You can also add custom buttons:
dialog := app.Dialog.Info().
SetMessage("Done!")
ok := dialog.AddButton("Got it!")
dialog.SetDefaultButton(ok)
dialog.Show()Beberapa tombol (Pertanyaan):
Use AddButton() to add buttons, which returns a *Button you can configure:
dialog := app.Dialog.Question().
SetMessage("Choose an action")
option1 := dialog.AddButton("Option 1")
option1.OnClick(func() {
handleOption1()
})
option2 := dialog.AddButton("Option 2")
option2.OnClick(func() {
handleOption2()
})
option3 := dialog.AddButton("Option 3")
option3.OnClick(func() {
handleOption3()
})
dialog.Show()Tombol Default dan Cancel:
Use SetDefaultButton() to specify which button is highlighted and triggered by Enter.
Use SetCancelButton() to specify which button is triggered by Escape.
dialog := app.Dialog.Question().
SetMessage("Delete file?")
deleteBtn := dialog.AddButton("Delete")
deleteBtn.OnClick(func() {
performDelete()
})
cancelBtn := dialog.AddButton("Cancel")
// No callback needed - just dismisses dialog
dialog.SetDefaultButton(cancelBtn) // Safe option as default
dialog.SetCancelButton(cancelBtn) // Escape triggers Cancel
dialog.Show()You can also use the fluent SetAsDefault() and SetAsCancel() methods on buttons:
dialog := app.Dialog.Question().
SetMessage("Delete file?")
dialog.AddButton("Delete").OnClick(func() {
performDelete()
})
dialog.AddButton("Cancel").SetAsDefault().SetAsCancel()
dialog.Show()Best practices:
- 1-3 buttons: Don’t overwhelm users
- Clear labels: “Save” not “OK”
- Safe default: Non-destructive action
- Order matters: Most likely action first (except Cancel)
Ikon Kustom
Set a custom icon for the dialog:
app.Dialog.Info().
SetTitle("Ikon Kustom Example").
SetMessage("Using a custom icon").
SetIcon(myIconBytes).
Show()Lampiran Window
Attach to specific window:
dialog := app.Dialog.Question().
SetMessage("Window-specific question").
AttachToWindow(window)
dialog.AddButton("OK")
dialog.Show()Benefits:
- dialog appears on correct window
- Parent window disabled whilst shown
- Better multi-window UX
Contoh Lengkap
Konfirmasi Aksi Destruktif
func deleteFiles(app *application.App, paths []string) {
// Confirm deletion
message := fmt.Sprintf("Delete %d file(s)?", len(paths))
if len(paths) == 1 {
message = fmt.Sprintf("Delete %s?", filepath.Base(paths[0]))
}
dialog := app.Dialog.Question().
SetTitle("Confirm Delete").
SetMessage(message)
deleteBtn := dialog.AddButton("Delete")
deleteBtn.OnClick(func() {
// Perform deletion
var errs []error
for _, path := range paths {
if err := os.Remove(path); err != nil {
errs = append(errs, err)
}
}
// Show result
if len(errs) > 0 {
app.Dialog.Error().
SetTitle("Delete Failed").
SetMessage(fmt.Sprintf("Failed to delete %d file(s)", len(errs))).
Show()
} else {
app.Dialog.Info().
SetTitle("Delete Complete").
SetMessage(fmt.Sprintf("Deleted %d file(s)", len(paths))).
Show()
}
})
cancelBtn := dialog.AddButton("Cancel")
dialog.SetDefaultButton(cancelBtn)
dialog.SetCancelButton(cancelBtn)
dialog.Show()
}Konfirmasi Keluar
func confirmQuit(app *application.App) {
dialog := app.Dialog.Question().
SetTitle("Quit").
SetMessage("You have unsaved work. Are you sure you want to quit?")
yes := dialog.AddButton("Yes")
yes.OnClick(func() {
app.Quit()
})
no := dialog.AddButton("No")
dialog.SetDefaultButton(no)
dialog.Show()
}Update Dialog with Download Option
func showUpdateDialog(app *application.App) {
dialog := app.Dialog.Question().
SetTitle("Update").
SetMessage("A new version is available. The cancel button is selected when pressing escape.")
download := dialog.AddButton("📥 Download")
download.OnClick(func() {
app.Dialog.Info().SetMessage("Downloading...").Show()
})
cancel := dialog.AddButton("Cancel")
dialog.SetDefaultButton(download)
dialog.SetCancelButton(cancel)
dialog.Show()
}Ikon Kustom Question
func showCustomIconQuestion(app *application.App, iconBytes []byte) {
dialog := app.Dialog.Question().
SetTitle("Ikon Kustom Example").
SetMessage("Using a custom icon").
SetIcon(iconBytes)
likeIt := dialog.AddButton("I like it!")
likeIt.OnClick(func() {
app.Dialog.Info().SetMessage("Thanks!").Show()
})
notKeen := dialog.AddButton("Not so keen...")
notKeen.OnClick(func() {
app.Dialog.Info().SetMessage("Too bad!").Show()
})
dialog.SetDefaultButton(likeIt)
dialog.Show()
}Praktik Terbaik
✅ Lakukan
- Be specific - “File saved to Documents” not “Success”
- Use appropriate type - Error for errors, Warning for warnings
- Provide context - Include relevant details
- Use clear button labels - “Delete” not “OK”
- Set safe defaults - Non-destructive action
- Handle cancellation - User might close dialog
❌ Jangan
- Don’t overuse - Interrupts workflow
- Don’t use for frequent updates - Use notifications instead
- Don’t use generic messages - “Error” tells nothing
- Don’t ignore errors - Handle dialog.Show() errors
- Don’t block unnecessarily - Consider async alternatives
- Don’t use technical jargon - Plain language
Perbedaan Platform
macOS
- Sheet-style when attached to window
- Standard keyboard shortcuts (⌘. for Cancel)
- Follows system theme automatically
- Accessibility built-in
Windows
- Dialog Modals
- TaskDialog appearance
- Esc for Cancel
- Follows system theme
Linux
- GTK dialogs
- Varies by desktop environment
- Follows desktop theme
- Standard keyboard navigation
Langkah Selanjutnya
Open, save, and folder selection.
Create custom dialog windows.
Non-intrusive notifications.
Use events for non-blocking communication.
Pertanyaan? Tanyakan di Discord or lihat dialog examples.