Dialogs & Modals
Relevant source files
The following files were used as context for generating this wiki page:
- src/app/script/klecks/ui/modals/base/showModal.ts
- src/app/script/klecks/ui/modals/text-tool-dialog/text-tool-dialog.ts
- src/app/script/klecks/ui/modals/licenses-dialog/show-licenses-dialog.ts
- src/app/script/app/kl-app.ts
- src/app/script/klecks/kl.ts
- src/app/script/klecks/ui/modals/base/dynamic-modal.ts
The Dialogs and Modals system in Rocreate provides a standardized framework for presenting interactive overlays, alerts, and tool-specific configurations to the user. It ensures consistency across the application by centralizing lifecycle management, event handling, and UI styling for all non-mainline interface components.
This system is built upon a base modal utility that handles the creation of the DOM structure, keyboard listeners (such as Escape for closing), and backdrop management. It supports various types of interactions, from simple informational alerts to complex multi-tabbed tool configuration dialogs like the Text Tool or the Licenses viewer. Sources: src/app/script/klecks/ui/modals/base/showModal.ts, src/app/script/klecks/ui/modals/text-tool-dialog/text-tool-dialog.ts
Core Architecture
The modal system relies on two primary entry points: showModal for standard dialogs and DynamicModal (or Popup) for more complex, flexible windows. These utilities are exported via the KL global object for application-wide accessibility. Sources: src/app/script/klecks/kl.ts:153-159
Modal Lifecycle and Counter
To prevent interface conflicts, the system maintains a global DIALOG_COUNTER. This counter is used to track the number of active modals and freeze background interactions (like the Easel) when a dialog is open.
The DIALOG_COUNTER notifies subscribers whenever the count changes, allowing the KlApp to lock or unlock the workspace accordingly. Sources: src/app/script/klecks/ui/modals/base/showModal.ts:25-26, src/app/script/app/kl-app.ts:601-603
The showModal Utility
The showModal function is the foundational tool for creating dialogs. It accepts a configuration object and returns a control interface for managing the modal's state (e.g., ignoring background clicks). Sources: src/app/script/klecks/ui/modals/base/showModal.ts:13-35
| Parameter | Type | Description |
|---|---|---|
target | HTMLElement | The parent element for the modal. |
message | string | Element | The primary content or HTML string to display. |
buttons | string[] | Array of button labels (e.g., ['Ok', 'Cancel']). |
type | 'error' | 'warning' | ... | Optional icon style to display in the box. |
callback | (result: string) => void | Invoked when the modal is closed with the button label. |
ignoreBackground | boolean | If true, clicking the backdrop does not close the modal. |
Sources: src/app/script/klecks/ui/modals/base/showModal.ts:13-24
Tool-Specific Dialogs
Complex tools utilize specialized dialog wrappers that combine the base modal system with custom UI components and viewport previews.
Text Tool Dialog
The Text Tool dialog implements a sophisticated multi-tabbed interface for editing text properties, font settings, and colors. It utilizes a TabRow to organize inputs and a TextToolViewportUI to provide live previews on the canvas. Sources: src/app/script/klecks/ui/modals/text-tool-dialog/text-tool-dialog.ts:23-91
The dialog manages the removal of event listeners (resize and scroll) and the destruction of sub-components upon exit to prevent memory leaks. Sources: src/app/script/klecks/ui/modals/text-tool-dialog/text-tool-dialog.ts:138-155
Licenses Dialog
The Licenses dialog leverages DynamicModal to show a large, scrollable window containing legal information for integrated libraries. It dynamically imports license content to reduce initial bundle size. Sources: src/app/script/klecks/ui/modals/licenses-dialog/show-licenses-dialog.ts:7-40
Implementation Details
Keyboard Handling
Modals implement a KeyListener to capture "Enter" (for confirming clickOnEnter buttons) and "Esc" (for closing/canceling). The system explicitly checks if an input is focused to avoid accidental closure while typing. Sources: src/app/script/klecks/ui/modals/base/showModal.ts:110-125
Background Interactions
When a modal is active:
- Page Scrolling: Custom scroll-fix logic and event listeners prevent the underlying page from scrolling, especially on mobile devices. Sources: src/app/script/klecks/ui/modals/base/showModal.ts:8, src/app/script/klecks/ui/modals/text-tool-dialog/text-tool-dialog.ts:133-136
- Wheel Events: The system prevents "Ctrl + Scroll" from zooming the page while the modal is open. Sources: src/app/script/klecks/ui/modals/base/showModal.ts:128-132
- Pointer Events: Toolspace interactions are typically disabled or "frozen" via the
DIALOG_COUNTERsubscription. Sources: src/app/script/app/kl-app.ts:601-603
UI Components and Icons
Modals use standardized icons for common actions, often derived from a Procreate-style aesthetic.
- Cancel/Close:
cancel.svg - Confirm/Ok:
check.svg - Delete:
remove-layer.svg
Sources: src/app/script/klecks/ui/modals/base/showModal.ts:8-11
The DynamicModal provides a higher-level abstraction for windows that require headers, footers, and specific widths (e.g., 800px for the licenses view). Sources: src/app/script/klecks/ui/modals/licenses-dialog/show-licenses-dialog.ts:12-23
Summary
The Dialogs and Modals system serves as the primary mechanism for user communication and complex input in Rocreate. By utilizing the DIALOG_COUNTER and a centralized showModal utility, the application maintains a predictable state where workspace interactions are paused during modal engagement. Specialized dialogs, such as the Text Tool, extend this base to provide feature-rich interfaces while inheriting the standard security and event-handling behaviors of the core modal system.