Skip to content

UX Improvements and Bug Fixes#12

Open
hrhv wants to merge 6 commits intomainfrom
ux-improvements
Open

UX Improvements and Bug Fixes#12
hrhv wants to merge 6 commits intomainfrom
ux-improvements

Conversation

@hrhv
Copy link
Copy Markdown
Member

@hrhv hrhv commented May 5, 2026

This pull request introduces a new session resumption flow to the ImageKit Editor, improves the user experience in the template dropdown, and fixes several UI consistency issues. The most significant change is the addition of a modal that prompts users to restore or discard unsaved session data, ensuring that work is not lost unexpectedly. Additionally, the template dropdown now displays skeleton loaders while fetching data, and there are improvements to gradient picker robustness and sidebar UI.

Session persistence and resumption:

  • Added a ResumeSessionModal component that appears when unsaved editor session data is detected, allowing users to restore their previous session or start a new one. This includes new logic in ImageKitEditor.tsx to detect and manage resumable sessions, and updates to EditorLayout and context providers to pause session persistence while the modal is open. [1] [2] [3] [4] [5] [6] [7] [8]

Template dropdown UX improvements:

  • Added skeleton loading indicators to the template dropdown for a smoother experience while templates are being fetched, and fixed various layout and accessibility issues. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]

Editor auto-save and session logic:

  • Updated tests and logic to ensure that auto-saving does not create new templates when there is no active template, preventing unintended data creation. [1] [2] [3]

Gradient picker robustness:

  • Improved the gradient picker to handle incomplete or invalid color inputs gracefully, ensuring the preview always displays a valid gradient and preventing crashes. [1] [2]

Sidebar and transformation UI:

  • Fixed a UI bug in the transformation sidebar where the renaming input was not properly wrapped, improving layout consistency.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds local session snapshot persistence and a resume/discard modal to avoid losing in-progress editor state, while also improving template browsing UX (skeleton loaders) and tightening a few UI behaviors (auto-save rules, gradient picker safety, sidebar layout).

Changes:

  • Added local session snapshot persistence (localStorage) and a ResumeSessionModal flow, including store support for restoring persisted state.
  • Improved template library/dropdown loading UX using skeleton placeholders.
  • Prevented auto-save from creating new templates when no template is active, and hardened gradient preview parsing against incomplete inputs.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/imagekit-editor-dev/src/store.ts Adds restoreSession action to hydrate resumable editor state into the store.
packages/imagekit-editor-dev/src/persistence/editorSessionStorage.ts Introduces versioned localStorage schema + read/write helpers for session snapshots.
packages/imagekit-editor-dev/src/ImageKitEditor.tsx Detects resumable sessions and renders the resume/discard modal; pauses persistence while modal is open.
packages/imagekit-editor-dev/src/hooks/useTemplateSync.ts Prevents auto-save paths from creating new templates when templateId is null.
packages/imagekit-editor-dev/src/hooks/usePersistedEditorSession.ts Subscribes to editor changes and persists snapshots to localStorage (debounced).
packages/imagekit-editor-dev/src/hooks/usePersistedEditorSession.test.tsx Adds tests for pause/unpause behavior of local session persistence.
packages/imagekit-editor-dev/src/components/templates/TemplatesLibraryView.tsx Replaces spinner-only loading state with a richer skeleton table placeholder.
packages/imagekit-editor-dev/src/components/sidebar/sortable-transformation-item.tsx Adjusts rename layout and reserves action space to reduce layout shift.
packages/imagekit-editor-dev/src/components/header/TemplateStatus.test.tsx Adds coverage to ensure auto-save doesn’t create templates on blank slate.
packages/imagekit-editor-dev/src/components/header/TemplatesDropdown.tsx Adds loading skeleton rows and minor sizing tweaks for dropdown content.
packages/imagekit-editor-dev/src/components/editor/ResumeSessionModal.tsx New modal prompting restore/discard of a detected unsaved session snapshot.
packages/imagekit-editor-dev/src/components/editor/layout.tsx Wires in session persistence hook with a pause flag.
packages/imagekit-editor-dev/src/components/editor/index.tsx Exports ResumeSessionModal.
packages/imagekit-editor-dev/src/components/common/GradientPicker.tsx Makes gradient preview generation resilient to incomplete/invalid hex inputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +139 to +148
const [resumeSession, setResumeSession] =
useState<PersistedEditorSession | null>(null)

React.useEffect(() => {
const resumableSession = readEditorSessionFromLocalStorage(
EDITOR_SESSION_STORAGE_KEY,
)
if (!resumableSession) return
setResumeSession(resumableSession)
}, [])
Comment on lines +80 to +93
function isValidSessionState(x: unknown): x is PersistedEditorSessionState {
const v = x as Record<string, unknown> | null
return (
!!v &&
typeof v === "object" &&
Array.isArray(v.transformations) &&
typeof v.visibleTransformations === "object" &&
typeof v.templateName === "string" &&
(typeof v.templateId === "string" || v.templateId === null) &&
(typeof v.templateIsPrivate === "boolean" ||
v.templateIsPrivate === null) &&
typeof v.isPristine === "boolean" &&
typeof v.localChangeVersion === "number" &&
typeof v.lastSyncedVersion === "number"
Comment on lines +231 to +235
minW="14"
justifyContent="flex-end"
opacity={isHover && !isRenaming ? 1 : 0}
pointerEvents={isHover && !isRenaming ? "auto" : "none"}
transition="opacity 0.15s"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants