Skip to content

Notice Component Actions: Missing Features and Limitations #74090

@manzoorwanijk

Description

@manzoorwanijk

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:

  1. Pass through all supported props to the underlying Button component instead of only passing a subset
  2. Properly implement openInNewTab by setting appropriate target and rel attributes when this prop is true
  3. Allow onClick to be called even when url is provided (matching the behavior of the Button component), enabling analytics tracking, confirmation dialogs, and custom link handling
  4. 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.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions