diff --git a/examples/vite-app/src/pages/showcase/data-table-lab/editing-errors-demo.tsx b/examples/vite-app/src/pages/showcase/data-table-lab/editing-errors-demo.tsx index 78e999ec..0a9d287a 100644 --- a/examples/vite-app/src/pages/showcase/data-table-lab/editing-errors-demo.tsx +++ b/examples/vite-app/src/pages/showcase/data-table-lab/editing-errors-demo.tsx @@ -18,6 +18,10 @@ type ErrorDemoRow = { const { column } = createColumnHelper(); function checkNote(value: string | null) { + if (value?.includes("!!")) + throw new Error( + "Notes can't contain repeated exclamation marks. Keep notes factual and send anything urgent to the receiving team through the comments panel so it is tracked against this purchase order.", + ); if (value?.includes("!")) throw new Error("Remove ! from the note"); } @@ -107,8 +111,8 @@ export function EditingErrorsDemo() {
  • In Draft note, type ! to throw from{" "} onValueChange. The failed draft stays visible and cannot be confirmed until - you remove !. Press Esc to restore the adopted note and clear its error - together. + you remove !. Type !! to see a longer message wrap. Press Esc to + restore the adopted note and clear its error together.
  • Set Async quantity to 13 and press Enter. The returned diff --git a/packages/core/src/components/data-table/editable-cell.tsx b/packages/core/src/components/data-table/editable-cell.tsx index 8cacabb8..c4f44735 100644 --- a/packages/core/src/components/data-table/editable-cell.tsx +++ b/packages/core/src/components/data-table/editable-cell.tsx @@ -128,7 +128,7 @@ const CELL_FOCUS_CLASS_NAME = cn( // Parsing and callback errors share the cell's error outline. const CELL_ERROR_CLASS_NAME = - "astw:ring-2 astw:ring-inset astw:ring-destructive astw:focus:ring-destructive astw:focus-visible:ring-destructive"; + "astw:ring-[1.5px] astw:ring-inset astw:ring-destructive astw:focus:ring-[1.5px] astw:focus:ring-destructive astw:focus-visible:ring-[1.5px] astw:focus-visible:ring-destructive"; // An editable cell says so at rest with a subtle tint instead of an icon. It's // a background *image* layered over whatever colour the cell already has (the @@ -181,6 +181,24 @@ interface CellErrorUI { containsTarget: (target: EventTarget | null) => boolean; } +// The standard popover body: the alert icon makes it read as an error rather +// than a tooltip. +function DefaultCellErrorContent({ message }: { message: string }) { + return ( +
    + {/* One line-height tall, so the icon centres on the first line of text. */} + + +

    {message}

    +
    + ); +} + function useCellValue>( row: TRow, col: EditableColumn, @@ -219,7 +237,11 @@ function useCellValue>( failure, id: errorId, message: renderError ? t("editCallbackError") : message, - content: renderError ? renderError({ row, error: failure.error }) : message, + content: renderError ? ( + renderError({ row, error: failure.error }) + ) : ( + + ), triggerRef, popupRef, containsTarget: containsErrorTarget, @@ -351,18 +373,31 @@ function EditableCellFrame({ aria-label={t("editShowError", { label })} aria-keyshortcuts="Alt+ArrowDown" tabIndex={-1} - className="astw:absolute astw:inset-y-0 astw:right-2 astw:z-10 astw:flex astw:items-center astw:text-destructive astw:outline-none astw:focus-visible:ring-2 astw:focus-visible:ring-destructive astw:[td:last-child>&]:right-6" + className="astw:absolute astw:inset-y-0 astw:right-2 astw:z-10 astw:flex astw:items-center astw:text-destructive astw:outline-none astw:[td:last-child>&]:right-6" onContextMenu={(event) => event.stopPropagation()} > -