-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
What problem does this address?
The Notice component's action buttons have several limitations that restrict their functionality in real-world use cases, as we have seen while working in Jetpack. I'm always frustrated when I need to use common button features like disabled states, loading indicators, or icons in notice actions, but they're not supported even though the underlying Button component supports them.
The current implementation has the following problems:
1. No Support for Disabled State
Action buttons cannot be disabled, which is problematic when an action is temporarily unavailable or being processed.
Current behavior:
<Notice
status="info"
actions={[
{
label: "Save Changes",
onClick: handleSave,
// No way to disable this while saving
}
]}
>
Settings updated
</Notice>2. No Support for Custom Button Size
The dismiss button uses size="small" (line 171), but action buttons don't support size customization, leading to inconsistent sizing options.
Current behavior:
// Action buttons are always default size (40px with __next40pxDefaultSize)
<Notice
actions={[
{
label: "Action",
onClick: handleAction,
// No size prop available
}
]}
/>3. onClick Ignored When URL is Provided
When both url and onClick are provided, the onClick is completely ignored. This prevents tracking analytics, confirmation dialogs, or handling link clicks with JavaScript.
Current behavior:
<Notice
actions={[
{
label: "View Details",
url: "/details",
onClick: (e) => {
// This onClick is NEVER called because url takes precedence
trackAnalytics('notice_action_clicked');
}
}
]}
/>4. No Support for Icon Buttons
Action buttons cannot include icons, which would improve visual clarity and accessibility.
5. No Support for Loading State
Actions cannot show loading indicators when processing asynchronous operations.
6. No Support for Tooltip/Help Text
Actions cannot provide additional context via tooltips.
7. Missing openInNewTab Implementation
The type definition includes openInNewTab?: boolean for NoticeActionWithURL, but it's never used in the implementation. The href prop is passed to Button without target="_blank" or rel="noopener noreferrer".
Current behavior:
<Notice
actions={[
{
label: "External Link",
url: "https://example.com",
openInNewTab: true, // This prop exists in types but does nothing!
}
]}
/>Impact
These limitations force us at Jetpack to:
- Create custom notice implementations when we need these features
- Use workarounds that may not be accessible or consistent with design patterns
- Miss opportunities for better UX (loading states, disabled states, icons, etc.)
What is your proposed solution?
Enhance the NoticeAction types to include commonly used Button props that are currently missing:
type CommonNoticeActionProps = {
label: string;
className?: string;
noDefaultClasses?: boolean;
variant?: 'primary' | 'secondary' | 'link';
disabled?: boolean;
size?: 'default' | 'compact' | 'small';
icon?: JSX.Element;
iconPosition?: 'left' | 'right';
iconSize?: number;
isBusy?: boolean;
isDestructive?: boolean;
tooltipPosition?: ComponentProps<typeof Button>['tooltipPosition'];
text?: string;
};Update the implementation to:
- Pass through all supported props to the underlying
Buttoncomponent instead of only passing a subset - Properly implement
openInNewTabby setting appropriatetargetandrelattributes when this prop is true - Allow
onClickto be called even whenurlis provided (matching the behavior of theButtoncomponent), enabling analytics tracking, confirmation dialogs, and custom link handling - Forward all other relevant Button props like
disabled,size,icon,isBusy, etc.
Example of expected usage after fix:
<Notice
status="success"
actions={[
{
label: "Save Changes",
onClick: handleSave,
disabled: isSaving,
isBusy: isSaving,
icon: saveIcon,
variant: "primary"
},
{
label: "Learn More",
url: "https://example.com/docs",
openInNewTab: true,
onClick: () => trackAnalytics('docs_clicked'),
icon: externalIcon,
size: "small"
}
]}
>
Settings updated successfully
</Notice>This would make Notice actions as flexible and feature-rich as standalone Button components, while maintaining consistency across the component library.