Skip to content

Conversation

pixel-perfectionist
Copy link
Member

@pixel-perfectionist pixel-perfectionist commented Sep 10, 2025

The design review highlighted that dot indicators alone don’t cover all carousel navigation needs.
This PR expands Fluent UI Storybook with numeric, alphabetical, and pagination CarouselNav stories, providing developers with flexible, ready-to-use navigation patterns.

Previous Behavior

Storybook only included the default CarouselNav example, limiting discoverability of other navigation patterns. Developers often had to experiment or build their own demos to explore alternative configurations.

New Behavior

New Stories Added

  • CarouselNavNumeric.stories.tsx: Numeric page buttons (1, 2, 3…).
image
  • CarouselNavAlphabetical.stories.tsx: Alphabetical page buttons (A, B, C…).
image
  • CarouselNavPagination.stories.tsx: Pagination control allowing direct page number input.
image
  • Implementation Notes
  • No changes were made to the core CarouselNav implementation, all updates are documentation-focused.

Copy link

github-actions bot commented Sep 10, 2025

📊 Bundle size report

✅ No changes found

@pixel-perfectionist pixel-perfectionist changed the title feat(carousel): Add carousel navigation story variants feat(carousel): Add stories for numeric, alphabetical, and carousel pagination variants Sep 10, 2025
Copy link

Pull request demo site: URL

{index + 1}
</button>
);
};
Copy link
Member

@layershifter layershifter Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a big fan of this approach it also breaks accessibility on CarouselNavButton (not the same role being applied):

image

Let's use recomposition instead, this will be more solid and future proof:

const CustomNavButton: ForwardRefComponent<CarouselNavButtonProps> = React.forwardRef((props, ref) => {
  const classes = useCustomNavButtonClasses();
  const state = useCarouselNavButton_unstable(props, ref);

  state.root.children = state.index;
  state.root.className = mergeClasses(classes.root, state.selected && classes.selected, state.root.className);

  return renderCarouselNavButton_unstable(state);
});
// packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButton.ts

  const state: CarouselNavButtonState = {
    selected,
    appearance,
    components: {
      root: 'button',
    },
    root: _carouselButton,
+   index
  };
// packages/react-components/react-carousel/library/src/components/CarouselNavButton/CarouselNavButton.types.ts

  /**
   * Enables selection state control
   */
  selected?: boolean;

+ index?: number;

</CarouselSlider>
</CarouselViewport>

<CarouselNav className={classes.nav}>{index => <CustomNavButton index={index} />}</CarouselNav>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image


return (
<div className={classes.paginationControls}>
<Input
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,184 @@
import {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to have this example this way? Have to say that UI has mixed user experience to suggest it to anybody...

Copy link
Member

@layershifter layershifter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please re-implement buttons & let's follow up on the pagination example in offline

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants