Ctrl K
ComunidadGuías…

components/InlineTitleEditor.tsx

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
'use client';

import { useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useTranslations } from 'next-intl';

export default function InlineTitleEditor({
  title,
  onRename,
}: {
  title: string;
  onRename: (title: string) => Promise<boolean>;
}) {
  const router = useRouter();
  const t = useTranslations('InlineTitle');
  const [value, setValue] = useState(title);
  const [saved, setSaved] = useState(title);
  // Escape blurs the input; that blur must not save the canceled edit.
  const canceled = useRef(false);

  const save = async () => {
    if (canceled.current) {
      canceled.current = false;
      return;
    }
    const newTitle = value.trim();
    if (!newTitle) {
      setValue(saved);
      return;
    }
    if (newTitle === saved) return;
    setValue(newTitle);
    try {
      if (await onRename(newTitle)) {
        setSaved(newTitle);
        router.refresh();
        return;
      }
    } catch {
      // fall through: restore the saved title so the user can retry
    }
    setValue(saved);
  };

  return (
    <input
      value={value}
      onChange={(e) => setValue(e.target.value)}
      onBlur={save}
      onKeyDown={(e) => {
        if (e.key === 'Enter' && !e.nativeEvent.isComposing) e.currentTarget.blur();
        if (e.key === 'Escape') {
          canceled.current = true;
          setValue(saved);
          e.currentTarget.blur();
        }
      }}
      maxLength={255}
      aria-label={t('titleLabel')}
      placeholder={t('titlePlaceholder')}
      className="w-full min-w-0 bg-transparent rounded-[8px] -mx-2 px-2 font-[inherit] tracking-[inherit] leading-[inherit] outline-none hover:bg-muted/50 focus:bg-muted/50 focus:ring-2 focus:ring-ring transition-colors"
    />
  );
}