Скилл переносится из ~/.claude/skills/aura-design в репозиторий обвязки: SKILL.md, справочники reference/ и набор kit/ (токены, base.css, компоненты React, оболочка AppShell, тест токенов, test-setup, примеры входа). install.sh ставит его в ~/.claude/skills/aura-design, --check его видит. tests/test-aura-design.sh проверяет структуру и инварианты набора. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
20 lines
1.4 KiB
TypeScript
20 lines
1.4 KiB
TypeScript
import { useEffect, useRef, type DialogHTMLAttributes, type ReactNode, type SyntheticEvent } from "react";
|
|
|
|
// окно: родной <dialog> держит фокус и закрывает фон; Esc — onClose, закрытие по фону — на стороне использующего.
|
|
// Остальные атрибуты <dialog> (onCancel, onClick, aria-labelledby …) проходят насквозь и могут переопределить поведение по
|
|
// умолчанию; нативное событие close — onNativeClose (имя onClose занято запросом закрытия).
|
|
type Rest = Omit<DialogHTMLAttributes<HTMLDialogElement>, "className" | "children" | "onClose" | "aria-label">;
|
|
export function Dialog({ label, onClose, onNativeClose, size = "md", className, children, ...rest }: {
|
|
label: string; onClose(): void; onNativeClose?(e: SyntheticEvent<HTMLDialogElement>): void;
|
|
size?: "sm" | "md" | "lg"; className?: string; children: ReactNode;
|
|
} & Rest) {
|
|
const ref = useRef<HTMLDialogElement>(null);
|
|
useEffect(() => { const d = ref.current; if (d && !d.open) d.showModal(); }, []);
|
|
return (
|
|
<dialog ref={ref} className={["ui-dialog", `ui-dialog--${size}`, className].filter(Boolean).join(" ")} aria-label={label}
|
|
onCancel={(e) => { e.preventDefault(); onClose(); }} {...rest} onClose={onNativeClose}>
|
|
{children}
|
|
</dialog>
|
|
);
|
|
}
|