Compare commits

...

1 Commits

Author SHA1 Message Date
Naiyuan Qing
7d55c4425d fix(skills): remove double-flicker on CreateSkillDialog close
CreateSkillDialog used a controlled \`open\` prop while staying mounted,
so closing meant a data-open → data-closed flip on the already-mounted
Popup plus a tail re-render from \`useEffect([open])\` resetting \`method\`.
Visible as a double-blink: first the close animation, then a second
fade when the reset effect fired.

Align with the CreateIssue / CreateProject pattern: parent conditionally
renders the dialog and \`<Dialog open>\` is hard-coded. Close now unmounts
the component and Base UI's Portal owns the single exit animation. The
per-open method reset becomes unnecessary — fresh mount, fresh state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:07:37 +08:00
2 changed files with 12 additions and 14 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { useEffect, useRef, useState } from "react";
import { useRef, useState } from "react";
import {
AlertCircle,
ArrowLeft,
@@ -452,21 +452,14 @@ const METHOD_DESCS: Record<Method, string> = {
};
export function CreateSkillDialog({
open,
onClose,
onCreated,
}: {
open: boolean;
onClose: () => void;
onCreated?: (skill: Skill) => void;
}) {
const [method, setMethod] = useState<Method>("chooser");
// Reset to chooser each time the dialog opens.
useEffect(() => {
if (open) setMethod("chooser");
}, [open]);
const handleCreated = (skill: Skill) => {
onCreated?.(skill);
onClose();
@@ -474,8 +467,12 @@ export function CreateSkillDialog({
const wide = method === "runtime";
// Mount pattern mirrors CreateIssue / CreateProject: the parent conditionally
// renders this component and `<Dialog open>` is hard-coded. Toggling `open`
// via prop (controlled) causes a second data-open → data-closed flip with a
// tail re-render, which shows up as a "double blink" on close.
return (
<Dialog open={open} onOpenChange={(v) => !v && onClose()}>
<Dialog open onOpenChange={(v) => !v && onClose()}>
<DialogContent
showCloseButton={false}
className={cn(

View File

@@ -538,11 +538,12 @@ export default function SkillsPage() {
</div>
)}
<CreateSkillDialog
open={createOpen}
onClose={() => setCreateOpen(false)}
onCreated={handleCreated}
/>
{createOpen && (
<CreateSkillDialog
onClose={() => setCreateOpen(false)}
onCreated={handleCreated}
/>
)}
</div>
);
}