From b852022317cebbc9f866075505e678c1b5d39e2b Mon Sep 17 00:00:00 2001 From: itsprade Date: Thu, 22 Oct 2026 15:18:22 +0530 Subject: [PATCH 1/4] feat(data-table): give the default cell-error popover an error look and undo hint The standard popover body showed only the message, so it read like a neutral tooltip. It now leads with a destructive alert icon, shows the message in medium weight, and adds the existing "Press Esc to undo" hint. Custom error.render content is unchanged. Co-Authored-By: Claude Opus 5.5 --- .../components/data-table/editable-cell.tsx | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/core/src/components/data-table/editable-cell.tsx b/packages/core/src/components/data-table/editable-cell.tsx index 8cacabb8..7ef34616 100644 --- a/packages/core/src/components/data-table/editable-cell.tsx +++ b/packages/core/src/components/data-table/editable-cell.tsx @@ -181,6 +181,23 @@ interface CellErrorUI { containsTarget: (target: EventTarget | null) => boolean; } +// The standard popover body: the error reads as an error (not a tooltip) and +// says how to get back to the adopted value. +function DefaultCellErrorContent({ message, hint }: { message: string; hint: string }) { + return ( +
+
+ ); +} + function useCellValue>( row: TRow, col: EditableColumn, @@ -219,7 +236,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, From 79df3aab1993198daa4351a026ad608fba1f1ecb Mon Sep 17 00:00:00 2001 From: itsprade Date: Thu, 22 Oct 2026 15:40:20 +0530 Subject: [PATCH 2/4] feat(data-table): tighten the cell-error popover Drop the undo hint and the popup border, reduce padding and cap the width at max-w-xs so long messages wrap. The lab's Draft note column now throws a longer message on "?" to show wrapping. Co-Authored-By: Claude Opus 5.5 --- .../data-table-lab/editing-errors-demo.tsx | 8 +++++-- .../components/data-table/editable-cell.tsx | 22 +++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) 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..478fd516 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 @@ -19,6 +19,10 @@ const { column } = createColumnHelper(); function checkNote(value: string | null) { if (value?.includes("!")) throw new Error("Remove ! from the note"); + if (value?.includes("?")) + throw new Error( + "Notes can't contain questions. Send open questions to the receiving team through the comments panel so they are tracked against this purchase order.", + ); } /** Callback failures use the table's default popover unless content is overridden. */ @@ -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 ? instead 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 7ef34616..333f0ea4 100644 --- a/packages/core/src/components/data-table/editable-cell.tsx +++ b/packages/core/src/components/data-table/editable-cell.tsx @@ -181,19 +181,16 @@ interface CellErrorUI { containsTarget: (target: EventTarget | null) => boolean; } -// The standard popover body: the error reads as an error (not a tooltip) and -// says how to get back to the adopted value. -function DefaultCellErrorContent({ message, hint }: { message: string; hint: string }) { +// The standard popover body: the alert icon makes it read as an error rather +// than a tooltip. +function DefaultCellErrorContent({ message }: { message: string }) { return ( -
    +
    ); } @@ -239,7 +236,7 @@ function useCellValue>( content: renderError ? ( renderError({ row, error: failure.error }) ) : ( - + ), triggerRef, popupRef, @@ -383,7 +380,10 @@ function EditableCellFrame({ ref={callbackError.popupRef} aria-label={t("editErrorDialog", { label })} data-slot="data-table-cell-error" - className={cn(POPUP_CLASS_NAME, "astw:max-w-sm astw:text-body-sm")} + className={cn( + POPUP_CLASS_NAME, + "astw:max-w-xs astw:border-0 astw:px-2.5 astw:py-2 astw:text-body-sm astw:outline-none", + )} onContextMenu={(event) => event.stopPropagation()} onTouchStart={(event) => event.stopPropagation()} onKeyDown={(event) => { From 3cc9b1f299f9e85277d72278371273ed9474659d Mon Sep 17 00:00:00 2001 From: itsprade Date: Thu, 22 Oct 2026 16:07:57 +0530 Subject: [PATCH 3/4] feat(data-table): refine cell-error popover placement and tint - 1px error ring on the cell, including while focused - popup opens directly under the cell, aligned to its left edge - light red tint (Alert's danger-surface) layered over the opaque popover colour so table lines don't show through; softer shadow-sm - icon centred on the first text line, at 70% of the text colour - lab: "!!" in Draft note throws a long message to show wrapping Co-Authored-By: Claude Opus 5.5 --- .../data-table-lab/editing-errors-demo.tsx | 10 ++++---- .../components/data-table/editable-cell.tsx | 24 +++++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) 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 478fd516..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,11 +18,11 @@ type ErrorDemoRow = { const { column } = createColumnHelper(); function checkNote(value: string | null) { - if (value?.includes("!")) throw new Error("Remove ! from the note"); - if (value?.includes("?")) + if (value?.includes("!!")) throw new Error( - "Notes can't contain questions. Send open questions to the receiving team through the comments panel so they are tracked against this purchase order.", + "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"); } /** Callback failures use the table's default popover unless content is overridden. */ @@ -111,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 !. Type ? instead to see a longer message wrap. 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 333f0ea4..f1fc00df 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 astw:ring-inset astw:ring-destructive astw:focus:ring-1 astw:focus:ring-destructive astw:focus-visible:ring-1 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 @@ -186,10 +186,10 @@ interface CellErrorUI { function DefaultCellErrorContent({ message }: { message: string }) { return (
    -
    ); @@ -375,14 +375,24 @@ function EditableCellFrame({