Skip to content

Core: Draw highlights on top of canvas and add various new features #30894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 45 commits into
base: next
Choose a base branch
from

Conversation

ghengeveld
Copy link
Member

@ghengeveld ghengeveld commented Mar 22, 2025

Closes #30968

What I did

  • Completely replaced the highlighting behavior to draw boxes on top of the canvas rather than adding CSS outlines to the existing elements.
  • Renamed elements option to selectors, which is more appropriate.
  • Replaced color and style options with styles. Boxes can be completely styled, there is no longer a limitation on which CSS properties are supported.
  • Added hoverStyles and focusStyles options to customize styling for hovered/focused/selected boxes.
  • Old API is still supported (automatically converted).
  • Added selectable option, which makes it possible to select boxes on the canvas. A popop/menu will appear with a list of targeted elements.
  • Added menu option which adds custom menu items to the popup. These can trigger a custom channel event when clicked, so it is up to whoever sets this up to setup an event listener.
  • Added priority option which serves as a tie-breaker when multiple highlights target the same element.
  • Added keyframes option which allows the use of animations in styles, hoverStyles or focusStyles.
  • Added REMOVE_HIGHLIGHT event which allows removal of individual highlights (contrary to RESET_HIGHLIGHT). Using this requires setting the new id option on the highlight.
  • Added SCROLL_INTO_VIEW event which allows scrolling an element into view and briefly highlighting it.

Play around with it here: https://highlight-overlay--635781f3500dd2c49e189caf.chromatic.com/?path=/story/blocks-controls-range--with-min&addonPanel=storybook/a11y/panel&a11ySelection=passes.color-contrast.4
Demo stories here: https://highlight-overlay--635781f3500dd2c49e189caf.chromatic.com/?path=/story/highlight-usehighlights--default
(note that if you want to try it on other stories through the a11y addon, you must refresh Storybook because these useHighlights stories override the global instance)

Screen.Recording.2025-03-31.at.15.37.51.mov

New API

interface HighlightOptions {
  /** Unique identifier for the highlight, required if you want to remove the highlight later */
  id?: string;
  /** HTML selectors of the elements */
  selectors: string[];
  /** Priority of the highlight, higher takes precedence, defaults to 0 */
  priority?: number;
  /** Whether the highlight is selectable (reveals the element's HTML) */
  selectable?: boolean;
  /** CSS styles to apply to the highlight */
  styles: Record<string, string>;
  /** CSS styles to apply to the highlight when it is hovered */
  hoverStyles?: Record<string, string>;
  /** CSS styles to apply to the highlight when it is focused or selected */
  focusStyles?: Record<string, string>;
  /** Keyframes required for animations */
  keyframes?: string;
  /** Menu items to show when the highlight is selected (implies selectable: true) */
  menu?: {
    /** Unique identifier for the menu item */
    id: string;
    /** Title of the menu item */
    title: string;
    /** Description of the menu item */
    description?: string;
    /** Name for a channel event to trigger when the menu item is clicked */
    clickEvent?: string;
    /** HTML selectors for which this menu item should show (subset of `selectors`) */
    selectors?: string[];
  }[];
}

// Add a highlight to the canvas:
channel.emit(HIGHLIGHT, /* HighlightOptions */ options);

// Remove a highlight:
channel.emit(REMOVE_HIGHLIGHT, /* string */ id);

// Remove all highlights:
channel.emit(RESET_HIGHLIGHT);

// Scroll an element into view and briefly highlight it:
channel.emit(SCROLL_INTO_VIEW, /* string */ targetSelector, /* ScrollIntoViewOptions */ options);

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>

Greptile Summary

This PR replaces the old CSS outline method with a new overlay mechanism that renders highlight boxes on top of the canvas, improving visual clarity and interaction.

• Modified /code/core/src/highlight/useHighlights.ts to implement reactive overlay boxes using MutationObserver and ResizeObserver.
• Updated /code/addons/a11y/src/components/A11yContext.tsx to handle selection and revamped highlight events.
• Added /code/core/src/highlight/useHighlights.stories.tsx to demonstrate various overlay scenarios.
• Adjusted /code/.storybook/main.ts to integrate the new highlight overlay story directory.
• Revised /code/core/src/highlight/utils.ts with enhanced createElement and noted a potential unsubscribe issue in useStore.

Copy link

nx-cloud bot commented Mar 22, 2025

View your CI Pipeline Execution ↗ for commit 31ccf9f.

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 1m 33s View ↗

☁️ Nx Cloud last updated this comment at 2025-04-17 15:14:35 UTC

@ghengeveld ghengeveld changed the base branch from next to a11y-polish March 25, 2025 09:52
Base automatically changed from a11y-polish to next March 27, 2025 10:08
@ghengeveld ghengeveld requested review from yannbf and JReinhold March 31, 2025 12:08
@ghengeveld ghengeveld marked this pull request as ready for review March 31, 2025 12:08
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

9 file(s) reviewed, 3 comment(s)
Edit PR Review Bot Settings | Greptile

@ghengeveld ghengeveld changed the title Addon Highlight: Render highlights on top of canvas Addon Highlight: Complete reimplementation to draw on top of elements and support popover menu Mar 31, 2025
@ghengeveld ghengeveld changed the title Addon Highlight: Complete reimplementation to draw on top of elements and support popover menu Core: Draw highlights on top of canvas and add various new features Apr 16, 2025
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.

[Bug]: Storybook 9 - A11y addon highlight does not work as expected
3 participants