Skip to content

Conversation

@shaneeza
Copy link
Collaborator

@shaneeza shaneeza commented Sep 19, 2025

✍️ Proposed changes

This PR enhances the drawer component by adding comprehensive focus management for embedded drawers. The changes ensure that when an embedded drawer is opened, focus automatically moves to the first focusable element within the drawer, and when closed, focus is restored to the previously focused element (typically the trigger button). This improves keyboard navigation and accessibility compliance.

🎟️ Jira ticket: No Jira ticket found

✅ Checklist

  • I have added stories/tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)
  • I have run pnpm changeset and documented my changes

🧪 How to test changes

  1. Test embedded drawer focus management:

    • Open an embedded drawer using a toolbar button or main content button
    • Verify focus moves to the first focusable element in the drawer
    • Close the drawer and verify focus returns to the original trigger element
  2. Test overlay drawer behavior:

    • Open an overlay drawer and verify existing focus behavior is maintained
    • Close the drawer and verify focus returns correctly
  3. Test accessibility with screen readers:

    • Open a drawer and verify the live region announces the drawer title
    • Navigate using keyboard only to ensure all focus transitions work smoothly
  4. Run the new interaction stories:

    • EmbeddedToolbarIsFocusedOnClose and EmbeddedButtonIsFocusedOnClose
    • OverlayToolbarIsFocusedOnClose and OverlayButtonIsFocusedOnClose

@changeset-bot
Copy link

changeset-bot bot commented Sep 19, 2025

🦋 Changeset detected

Latest commit: df328af

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@leafygreen-ui/drawer Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@shaneeza shaneeza requested a review from Copilot September 19, 2025 01:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds comprehensive focus management to embedded drawers, enhancing accessibility and keyboard navigation. When an embedded drawer opens, focus automatically moves to the first focusable element within the drawer, and when closed, focus is restored to the previously focused element.

Key changes:

  • Implements focus management logic in PanelGrid component for embedded drawers
  • Removes redundant focus handling and ARIA attributes from existing components
  • Adds interaction stories to test focus behavior for both embedded and overlay drawer modes

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/drawer/src/LayoutComponent/PanelGrid/PanelGrid.tsx Adds focus management logic with useIsomorphicLayoutEffect to handle focus transitions
packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayoutContent.tsx Removes redundant aria-live attributes that are now handled elsewhere
packages/drawer/src/DrawerToolbarLayout/DrawerToolbarLayout/DrawerToolbarLayout.interactions.stories.tsx Adds comprehensive interaction stories to test focus management behavior
packages/drawer/src/Drawer/Drawer.tsx Removes old focus handling logic and adds VisuallyHidden live region for screen reader announcements
.changeset/beige-lights-kick.md Documents the changes for release notes

@github-actions
Copy link
Contributor

github-actions bot commented Sep 19, 2025

Size Change: +141 B (+0.01%)

Total Size: 1.6 MB

Filename Size Change
packages/drawer/dist/esm/index.js 8.08 kB +142 B (+1.79%)
packages/drawer/dist/esm/testing/index.js 425 B -65 B (-13.27%) 👏
packages/drawer/dist/umd/index.js 8.26 kB +128 B (+1.57%)
packages/drawer/dist/umd/testing/index.js 546 B -64 B (-10.49%) 👏
ℹ️ View Unchanged
Filename Size
charts/chart-card/dist/esm/index.js 2.78 kB
charts/chart-card/dist/umd/index.js 2.94 kB
charts/colors/dist/esm/index.js 530 B
charts/colors/dist/umd/index.js 657 B
charts/core/dist/esm/index.js 16.1 kB
charts/core/dist/umd/index.js 16.4 kB
charts/drag-provider/dist/esm/index.js 1.37 kB
charts/drag-provider/dist/umd/index.js 1.49 kB
charts/legend/dist/esm/index.js 1.52 kB
charts/legend/dist/umd/index.js 1.69 kB
charts/series-provider/dist/esm/index.js 1.28 kB
charts/series-provider/dist/umd/index.js 1.41 kB
chat/avatar/dist/esm/index.js 1.36 kB
chat/avatar/dist/umd/index.js 1.53 kB
chat/chat-window/dist/esm/index.js 1.67 kB
chat/chat-window/dist/umd/index.js 1.85 kB
chat/fixed-chat-window/dist/esm/index.js 2.4 kB
chat/fixed-chat-window/dist/umd/index.js 2.59 kB
chat/input-bar/dist/esm/index.js 7.74 kB
chat/input-bar/dist/umd/index.js 7.98 kB
chat/leafygreen-chat-provider/dist/esm/index.js 957 B
chat/leafygreen-chat-provider/dist/umd/index.js 1.11 kB
chat/lg-markdown/dist/esm/index.js 2.19 kB
chat/lg-markdown/dist/umd/index.js 2.33 kB
chat/message-feed/dist/esm/index.js 2.8 kB
chat/message-feed/dist/umd/index.js 3.03 kB
chat/message-feedback/dist/esm/index.js 4.52 kB
chat/message-feedback/dist/umd/index.js 4.74 kB
chat/message-prompts/dist/esm/index.js 2.25 kB
chat/message-prompts/dist/umd/index.js 2.42 kB
chat/message-rating/dist/esm/index.js 2.58 kB
chat/message-rating/dist/umd/index.js 2.78 kB
chat/message/dist/esm/index.js 8.27 kB
chat/message/dist/umd/index.js 8.53 kB
chat/rich-links/dist/esm/index.js 2.38 kB
chat/rich-links/dist/umd/index.js 2.58 kB
chat/suggestions/dist/esm/index.js 1.65 kB
chat/suggestions/dist/esm/testing/index.js 55 B
chat/suggestions/dist/umd/index.js 1.84 kB
chat/suggestions/dist/umd/testing/index.js 113 B
chat/title-bar/dist/esm/index.js 1.38 kB
chat/title-bar/dist/umd/index.js 1.6 kB
packages/a11y/dist/esm/index.js 1.71 kB
packages/a11y/dist/umd/index.js 1.83 kB
packages/avatar/dist/esm/index.js 3.4 kB
packages/avatar/dist/umd/index.js 3.58 kB
packages/badge/dist/esm/index.js 1.47 kB
packages/badge/dist/umd/index.js 1.67 kB
packages/banner/dist/esm/index.js 3.2 kB
packages/banner/dist/umd/index.js 3.51 kB
packages/button/dist/esm/constants.js 121 B
packages/button/dist/esm/index.js 4.8 kB
packages/button/dist/esm/testing/index.js 321 B
packages/button/dist/umd/constants.js 262 B
packages/button/dist/umd/index.js 4.99 kB
packages/button/dist/umd/testing/index.js 443 B
packages/callout/dist/esm/index.js 1.55 kB
packages/callout/dist/umd/index.js 1.74 kB
packages/card/dist/esm/index.js 1.52 kB
packages/card/dist/umd/index.js 1.71 kB
packages/checkbox/dist/esm/index.js 4.28 kB
packages/checkbox/dist/umd/index.js 4.48 kB
packages/chip/dist/esm/index.js 3.21 kB
packages/chip/dist/umd/index.js 3.42 kB
packages/code-editor/dist/esm/index.js 15.5 kB
packages/code-editor/dist/esm/testing/index.js 4.2 kB
packages/code-editor/dist/umd/index.js 15.7 kB
packages/code-editor/dist/umd/testing/index.js 4.34 kB
packages/code/dist/esm/index.js 10.5 kB
packages/code/dist/esm/testing/index.js 11.3 kB
packages/code/dist/umd/index.js 11.2 kB
packages/code/dist/umd/testing/index.js 12 kB
packages/combobox/dist/esm/index.js 11.5 kB
packages/combobox/dist/umd/index.js 11.8 kB
packages/compound-component/dist/esm/index.js 1.09 kB
packages/compound-component/dist/umd/index.js 1.17 kB
packages/confirmation-modal/dist/esm/index.js 2.62 kB
packages/confirmation-modal/dist/umd/index.js 2.84 kB
packages/context-drawer/dist/esm/index.js 3.12 kB
packages/context-drawer/dist/esm/testing/index.js 3.52 kB
packages/context-drawer/dist/umd/index.js 3.29 kB
packages/context-drawer/dist/umd/testing/index.js 3.68 kB
packages/copyable/dist/esm/index.js 2.78 kB
packages/copyable/dist/umd/index.js 2.99 kB
packages/date-picker/dist/esm/index.js 13.7 kB
packages/date-picker/dist/umd/index.js 14.1 kB
packages/date-utils/dist/esm/index.js 2.7 kB
packages/date-utils/dist/esm/testing/index.js 1.35 kB
packages/date-utils/dist/umd/index.js 2.8 kB
packages/date-utils/dist/umd/testing/index.js 1.49 kB
packages/descendants/dist/esm/index.js 2.81 kB
packages/descendants/dist/umd/index.js 2.93 kB
packages/emotion/dist/esm/index.js 357 B
packages/emotion/dist/umd/index.js 571 B
packages/empty-state/dist/esm/index.js 1.75 kB
packages/empty-state/dist/umd/index.js 1.94 kB
packages/expandable-card/dist/esm/index.js 2.95 kB
packages/expandable-card/dist/esm/testing/index.js 3.47 kB
packages/expandable-card/dist/umd/index.js 3.19 kB
packages/expandable-card/dist/umd/testing/index.js 3.68 kB
packages/form-field/dist/esm/index.js 4.37 kB
packages/form-field/dist/umd/index.js 4.54 kB
packages/form-footer/dist/esm/index.js 1.69 kB
packages/form-footer/dist/umd/index.js 1.92 kB
packages/gallery-indicator/dist/esm/index.js 1.39 kB
packages/gallery-indicator/dist/esm/testing/index.js 351 B
packages/gallery-indicator/dist/umd/index.js 1.55 kB
packages/gallery-indicator/dist/umd/testing/index.js 481 B
packages/guide-cue/dist/esm/index.js 5.17 kB
packages/guide-cue/dist/umd/index.js 5.38 kB
packages/hooks/dist/esm/index.js 3.62 kB
packages/hooks/dist/umd/index.js 3.75 kB
packages/icon-button/dist/esm/index.js 2.28 kB
packages/icon-button/dist/umd/index.js 2.49 kB
packages/icon/dist/esm/ActivityFeed.js 1.11 kB
packages/icon/dist/esm/AddFile.js 903 B
packages/icon/dist/esm/AIModel.js 772 B
packages/icon/dist/esm/AllProducts.js 995 B
packages/icon/dist/esm/AnalyticsNode.js 762 B
packages/icon/dist/esm/Apps.js 604 B
packages/icon/dist/esm/Array.js 718 B
packages/icon/dist/esm/ArrowDown.js 828 B
packages/icon/dist/esm/ArrowLeft.js 833 B
packages/icon/dist/esm/ArrowRight.js 828 B
packages/icon/dist/esm/ArrowUp.js 828 B
packages/icon/dist/esm/Award.js 1.24 kB
packages/icon/dist/esm/Beaker.js 1.24 kB
packages/icon/dist/esm/Bell.js 797 B
packages/icon/dist/esm/Biometric.js 1.33 kB
packages/icon/dist/esm/Boolean.js 648 B
packages/icon/dist/esm/Building.js 793 B
packages/icon/dist/esm/Bulb.js 828 B
packages/icon/dist/esm/Calendar.js 794 B
packages/icon/dist/esm/Camera.js 874 B
packages/icon/dist/esm/Cap.js 976 B
packages/icon/dist/esm/CaretDown.js 665 B
packages/icon/dist/esm/CaretLeft.js 662 B
packages/icon/dist/esm/CaretRight.js 657 B
packages/icon/dist/esm/CaretUp.js 664 B
packages/icon/dist/esm/ChartFilled.js 761 B
packages/icon/dist/esm/Charts.js 745 B
packages/icon/dist/esm/Checkmark.js 789 B
packages/icon/dist/esm/CheckmarkWithCircle.js 851 B
packages/icon/dist/esm/ChevronDown.js 763 B
packages/icon/dist/esm/ChevronLeft.js 763 B
packages/icon/dist/esm/ChevronRight.js 772 B
packages/icon/dist/esm/ChevronUp.js 754 B
packages/icon/dist/esm/Circle.js 545 B
packages/icon/dist/esm/Clock.js 816 B
packages/icon/dist/esm/ClockWithArrow.js 1.06 kB
packages/icon/dist/esm/Clone.js 700 B
packages/icon/dist/esm/Cloud.js 861 B
packages/icon/dist/esm/Code.js 1.05 kB
packages/icon/dist/esm/CodeBlock.js 997 B
packages/icon/dist/esm/Coin.js 1.1 kB
packages/icon/dist/esm/Colon.js 654 B
packages/icon/dist/esm/Config.js 946 B
packages/icon/dist/esm/Connect.js 1.09 kB
packages/icon/dist/esm/Copy.js 1.04 kB
packages/icon/dist/esm/CreditCard.js 626 B
packages/icon/dist/esm/CurlyBraces.js 1.2 kB
packages/icon/dist/esm/Cursor.js 747 B
packages/icon/dist/esm/Dashboard.js 767 B
packages/icon/dist/esm/Database.js 1.19 kB
packages/icon/dist/esm/Diagram.js 840 B
packages/icon/dist/esm/Diagram2.js 845 B
packages/icon/dist/esm/Diagram3.js 824 B
packages/icon/dist/esm/Disconnect.js 1.04 kB
packages/icon/dist/esm/Download.js 962 B
packages/icon/dist/esm/Drag.js 808 B
packages/icon/dist/esm/Edit.js 707 B
packages/icon/dist/esm/Ellipsis.js 699 B
packages/icon/dist/esm/Email.js 884 B
packages/icon/dist/esm/EmptyDatabase.js 3.36 kB
packages/icon/dist/esm/EmptyFolder.js 1.27 kB
packages/icon/dist/esm/Eraser.js 947 B
packages/icon/dist/esm/Escalation.js 846 B
packages/icon/dist/esm/Export.js 958 B
packages/icon/dist/esm/Favorite.js 907 B
packages/icon/dist/esm/Federation.js 1.21 kB
packages/icon/dist/esm/File.js 732 B
packages/icon/dist/esm/Filter.js 719 B
packages/icon/dist/esm/Folder.js 637 B
packages/icon/dist/esm/Format.js 1.04 kB
packages/icon/dist/esm/FullScreenEnter.js 884 B
packages/icon/dist/esm/FullScreenExit.js 890 B
packages/icon/dist/esm/Function.js 1.85 kB
packages/icon/dist/esm/Gauge.js 899 B
packages/icon/dist/esm/GlobeAmericas.js 831 B
packages/icon/dist/esm/glyphCommon-D-w_icbF.js 814 B
packages/icon/dist/esm/GovernmentBuilding.js 871 B
packages/icon/dist/esm/Guide.js 1.16 kB
packages/icon/dist/esm/Hash.js 1.01 kB
packages/icon/dist/esm/HiddenSecondaryNode.js 2.24 kB
packages/icon/dist/esm/Highlight.js 1.04 kB
packages/icon/dist/esm/Home.js 970 B
packages/icon/dist/esm/HorizontalDrag.js 816 B
packages/icon/dist/esm/Import.js 951 B
packages/icon/dist/esm/ImportantWithCircle.js 735 B
packages/icon/dist/esm/index.js 35.2 kB
packages/icon/dist/esm/InfoWithCircle.js 765 B
packages/icon/dist/esm/InternalEmployee.js 1.03 kB
packages/icon/dist/esm/InviteUser.js 1.05 kB
packages/icon/dist/esm/Key.js 866 B
packages/icon/dist/esm/Laptop.js 849 B
packages/icon/dist/esm/LightningBolt.js 729 B
packages/icon/dist/esm/Link.js 1.19 kB
packages/icon/dist/esm/List.js 875 B
packages/icon/dist/esm/Lock.js 818 B
packages/icon/dist/esm/LogIn.js 889 B
packages/icon/dist/esm/LogOut.js 946 B
packages/icon/dist/esm/MagnifyingGlass.js 798 B
packages/icon/dist/esm/Megaphone.js 771 B
packages/icon/dist/esm/Menu.js 690 B
packages/icon/dist/esm/Minus.js 641 B
packages/icon/dist/esm/Mobile.js 641 B
packages/icon/dist/esm/Moon.js 808 B
packages/icon/dist/esm/MultiDirectionArrow.js 844 B
packages/icon/dist/esm/MultiLayers.js 1.77 kB
packages/icon/dist/esm/NavCollapse.js 864 B
packages/icon/dist/esm/NavExpand.js 872 B
packages/icon/dist/esm/NoFilter.js 848 B
packages/icon/dist/esm/NotAllowed.js 749 B
packages/icon/dist/esm/Note.js 783 B
packages/icon/dist/esm/NumberedList.js 1.63 kB
packages/icon/dist/esm/OpenNewTab.js 1.03 kB
packages/icon/dist/esm/OutlineFavorite.js 1.17 kB
packages/icon/dist/esm/Package.js 1.02 kB
packages/icon/dist/esm/Pause.js 689 B
packages/icon/dist/esm/Pending.js 672 B
packages/icon/dist/esm/Person.js 845 B
packages/icon/dist/esm/PersonGroup.js 1.04 kB
packages/icon/dist/esm/PersonWithLock.js 1.04 kB
packages/icon/dist/esm/Pin.js 792 B
packages/icon/dist/esm/Play.js 675 B
packages/icon/dist/esm/Plus.js 698 B
packages/icon/dist/esm/PlusWithCircle.js 728 B
packages/icon/dist/esm/Primary.js 745 B
packages/icon/dist/esm/Project.js 784 B
packages/icon/dist/esm/QuestionMarkWithCircle.js 1.07 kB
packages/icon/dist/esm/Read.js 1.35 kB
packages/icon/dist/esm/Recommended.js 1.52 kB
packages/icon/dist/esm/Redo.js 1 kB
packages/icon/dist/esm/Refresh.js 1.07 kB
packages/icon/dist/esm/Relationship.js 791 B
packages/icon/dist/esm/ReplicaSet.js 936 B
packages/icon/dist/esm/Resize.js 764 B
packages/icon/dist/esm/Resource.js 1.07 kB
packages/icon/dist/esm/Return.js 849 B
packages/icon/dist/esm/Revert.js 881 B
packages/icon/dist/esm/Router.js 1.53 kB
packages/icon/dist/esm/Save.js 1.26 kB
packages/icon/dist/esm/SearchIndex.js 1.39 kB
packages/icon/dist/esm/Secondary.js 963 B
packages/icon/dist/esm/Serverless.js 913 B
packages/icon/dist/esm/Settings.js 1.33 kB
packages/icon/dist/esm/ShardedCluster.js 1.29 kB
packages/icon/dist/esm/Shell.js 839 B
packages/icon/dist/esm/Shield.js 1.24 kB
packages/icon/dist/esm/Shirt.js 792 B
packages/icon/dist/esm/Shortcut.js 1.33 kB
packages/icon/dist/esm/SMS.js 805 B
packages/icon/dist/esm/SortAscending.js 885 B
packages/icon/dist/esm/SortDescending.js 877 B
packages/icon/dist/esm/Sparkle.js 1.19 kB
packages/icon/dist/esm/SplitHorizontal.js 662 B
packages/icon/dist/esm/SplitVertical.js 658 B
packages/icon/dist/esm/Stitch.js 698 B
packages/icon/dist/esm/Stop.js 550 B
packages/icon/dist/esm/Streaming.js 1.63 kB
packages/icon/dist/esm/String.js 795 B
packages/icon/dist/esm/Sun.js 1.01 kB
packages/icon/dist/esm/Support.js 876 B
packages/icon/dist/esm/Sweep.js 905 B
packages/icon/dist/esm/Table.js 684 B
packages/icon/dist/esm/Tag.js 723 B
packages/icon/dist/esm/TemporaryTable.js 905 B
packages/icon/dist/esm/ThumbsDown.js 983 B
packages/icon/dist/esm/ThumbsUp.js 983 B
packages/icon/dist/esm/TimeSeries.js 1.02 kB
packages/icon/dist/esm/TimeSeriesCollection.js 1.15 kB
packages/icon/dist/esm/Trash.js 713 B
packages/icon/dist/esm/Undo.js 993 B
packages/icon/dist/esm/University.js 1.19 kB
packages/icon/dist/esm/Unlock.js 885 B
packages/icon/dist/esm/Unsorted.js 928 B
packages/icon/dist/esm/UpDownCarets.js 787 B
packages/icon/dist/esm/Upload.js 970 B
packages/icon/dist/esm/VerticalEllipsis.js 709 B
packages/icon/dist/esm/View.js 841 B
packages/icon/dist/esm/Visibility.js 995 B
packages/icon/dist/esm/VisibilityOff.js 1.37 kB
packages/icon/dist/esm/Warning.js 779 B
packages/icon/dist/esm/Wizard.js 1.09 kB
packages/icon/dist/esm/Wrench.js 1.09 kB
packages/icon/dist/esm/Write.js 1.36 kB
packages/icon/dist/esm/X.js 820 B
packages/icon/dist/esm/XWithCircle.js 766 B
packages/icon/dist/umd/ActivityFeed.js 1.96 kB
packages/icon/dist/umd/AddFile.js 1.73 kB
packages/icon/dist/umd/AIModel.js 1.57 kB
packages/icon/dist/umd/AllProducts.js 1.99 kB
packages/icon/dist/umd/AnalyticsNode.js 1.57 kB
packages/icon/dist/umd/Apps.js 1.41 kB
packages/icon/dist/umd/Array.js 1.52 kB
packages/icon/dist/umd/ArrowDown.js 1.65 kB
packages/icon/dist/umd/ArrowLeft.js 1.66 kB
packages/icon/dist/umd/ArrowRight.js 1.65 kB
packages/icon/dist/umd/ArrowUp.js 1.65 kB
packages/icon/dist/umd/Award.js 2.09 kB
packages/icon/dist/umd/Beaker.js 2.08 kB
packages/icon/dist/umd/Bell.js 1.61 kB
packages/icon/dist/umd/Biometric.js 2.18 kB
packages/icon/dist/umd/Boolean.js 1.45 kB
packages/icon/dist/umd/Building.js 1.6 kB
packages/icon/dist/umd/Bulb.js 1.65 kB
packages/icon/dist/umd/Calendar.js 1.6 kB
packages/icon/dist/umd/Camera.js 1.69 kB
packages/icon/dist/umd/Cap.js 1.81 kB
packages/icon/dist/umd/CaretDown.js 1.47 kB
packages/icon/dist/umd/CaretLeft.js 1.47 kB
packages/icon/dist/umd/CaretRight.js 1.46 kB
packages/icon/dist/umd/CaretUp.js 1.47 kB
packages/icon/dist/umd/ChartFilled.js 1.57 kB
packages/icon/dist/umd/Charts.js 1.54 kB
packages/icon/dist/umd/Checkmark.js 1.61 kB
packages/icon/dist/umd/CheckmarkWithCircle.js 1.68 kB
packages/icon/dist/umd/ChevronDown.js 1.57 kB
packages/icon/dist/umd/ChevronLeft.js 1.57 kB
packages/icon/dist/umd/ChevronRight.js 1.59 kB
packages/icon/dist/umd/ChevronUp.js 1.56 kB
packages/icon/dist/umd/Circle.js 1.53 kB
packages/icon/dist/umd/Clock.js 1.63 kB
packages/icon/dist/umd/ClockWithArrow.js 1.92 kB
packages/icon/dist/umd/Clone.js 1.5 kB
packages/icon/dist/umd/Cloud.js 1.68 kB
packages/icon/dist/umd/Code.js 1.89 kB
packages/icon/dist/umd/CodeBlock.js 1.83 kB
packages/icon/dist/umd/Coin.js 1.94 kB
packages/icon/dist/umd/Colon.js 1.45 kB
packages/icon/dist/umd/Config.js 1.77 kB
packages/icon/dist/umd/Connect.js 1.93 kB
packages/icon/dist/umd/Copy.js 1.88 kB
packages/icon/dist/umd/CreditCard.js 1.43 kB
packages/icon/dist/umd/CurlyBraces.js 2.03 kB
packages/icon/dist/umd/Cursor.js 1.56 kB
packages/icon/dist/umd/Dashboard.js 1.57 kB
packages/icon/dist/umd/Database.js 2.03 kB
packages/icon/dist/umd/Diagram.js 1.65 kB
packages/icon/dist/umd/Diagram2.js 1.66 kB
packages/icon/dist/umd/Diagram3.js 1.63 kB
packages/icon/dist/umd/Disconnect.js 1.86 kB
packages/icon/dist/umd/Download.js 1.79 kB
packages/icon/dist/umd/Drag.js 1.61 kB
packages/icon/dist/umd/Edit.js 1.52 kB
packages/icon/dist/umd/Ellipsis.js 1.5 kB
packages/icon/dist/umd/Email.js 1.71 kB
packages/icon/dist/umd/EmptyDatabase.js 4.3 kB
packages/icon/dist/umd/EmptyFolder.js 2.1 kB
packages/icon/dist/umd/Eraser.js 1.78 kB
packages/icon/dist/umd/Escalation.js 1.68 kB
packages/icon/dist/umd/Export.js 1.78 kB
packages/icon/dist/umd/Favorite.js 1.74 kB
packages/icon/dist/umd/Federation.js 2.06 kB
packages/icon/dist/umd/File.js 1.54 kB
packages/icon/dist/umd/Filter.js 1.53 kB
packages/icon/dist/umd/Folder.js 1.43 kB
packages/icon/dist/umd/Format.js 1.86 kB
packages/icon/dist/umd/FullScreenEnter.js 1.69 kB
packages/icon/dist/umd/FullScreenExit.js 1.7 kB
packages/icon/dist/umd/Function.js 2.75 kB
packages/icon/dist/umd/Gauge.js 1.73 kB
packages/icon/dist/umd/GlobeAmericas.js 1.65 kB
packages/icon/dist/umd/GovernmentBuilding.js 1.68 kB
packages/icon/dist/umd/Guide.js 2 kB
packages/icon/dist/umd/Hash.js 1.83 kB
packages/icon/dist/umd/HiddenSecondaryNode.js 3.11 kB
packages/icon/dist/umd/Highlight.js 1.88 kB
packages/icon/dist/umd/Home.js 1.8 kB
packages/icon/dist/umd/HorizontalDrag.js 1.62 kB
packages/icon/dist/umd/Import.js 1.78 kB
packages/icon/dist/umd/ImportantWithCircle.js 1.54 kB
packages/icon/dist/umd/index.js 35.5 kB
packages/icon/dist/umd/InfoWithCircle.js 1.57 kB
packages/icon/dist/umd/InternalEmployee.js 1.87 kB
packages/icon/dist/umd/InviteUser.js 1.88 kB
packages/icon/dist/umd/Key.js 1.68 kB
packages/icon/dist/umd/Laptop.js 1.67 kB
packages/icon/dist/umd/LightningBolt.js 1.54 kB
packages/icon/dist/umd/Link.js 2.04 kB
packages/icon/dist/umd/List.js 1.68 kB
packages/icon/dist/umd/Lock.js 1.64 kB
packages/icon/dist/umd/LogIn.js 1.71 kB
packages/icon/dist/umd/LogOut.js 1.77 kB
packages/icon/dist/umd/MagnifyingGlass.js 1.6 kB
packages/icon/dist/umd/Megaphone.js 1.58 kB
packages/icon/dist/umd/Menu.js 1.49 kB
packages/icon/dist/umd/Minus.js 1.44 kB
packages/icon/dist/umd/Mobile.js 1.44 kB
packages/icon/dist/umd/Moon.js 1.63 kB
packages/icon/dist/umd/MultiDirectionArrow.js 1.66 kB
packages/icon/dist/umd/MultiLayers.js 2.63 kB
packages/icon/dist/umd/NavCollapse.js 1.68 kB
packages/icon/dist/umd/NavExpand.js 1.69 kB
packages/icon/dist/umd/NoFilter.js 1.67 kB
packages/icon/dist/umd/NotAllowed.js 1.55 kB
packages/icon/dist/umd/Note.js 1.59 kB
packages/icon/dist/umd/NumberedList.js 2.5 kB
packages/icon/dist/umd/OpenNewTab.js 1.88 kB
packages/icon/dist/umd/OutlineFavorite.js 2.01 kB
packages/icon/dist/umd/Package.js 1.85 kB
packages/icon/dist/umd/Pause.js 1.49 kB
packages/icon/dist/umd/Pending.js 1.47 kB
packages/icon/dist/umd/Person.js 1.67 kB
packages/icon/dist/umd/PersonGroup.js 1.87 kB
packages/icon/dist/umd/PersonWithLock.js 1.87 kB
packages/icon/dist/umd/Pin.js 1.61 kB
packages/icon/dist/umd/Play.js 1.48 kB
packages/icon/dist/umd/Plus.js 1.5 kB
packages/icon/dist/umd/PlusWithCircle.js 1.53 kB
packages/icon/dist/umd/Primary.js 1.55 kB
packages/icon/dist/umd/Project.js 1.59 kB
packages/icon/dist/umd/QuestionMarkWithCircle.js 1.91 kB
packages/icon/dist/umd/Read.js 2.2 kB
packages/icon/dist/umd/Recommended.js 2.38 kB
packages/icon/dist/umd/Redo.js 2.04 kB
packages/icon/dist/umd/Refresh.js 1.91 kB
packages/icon/dist/umd/Relationship.js 1.6 kB
packages/icon/dist/umd/ReplicaSet.js 1.76 kB
packages/icon/dist/umd/Resize.js 1.76 kB
packages/icon/dist/umd/Resource.js 1.9 kB
packages/icon/dist/umd/Return.js 1.67 kB
packages/icon/dist/umd/Revert.js 1.71 kB
packages/icon/dist/umd/Router.js 2.38 kB
packages/icon/dist/umd/Save.js 2.1 kB
packages/icon/dist/umd/SearchIndex.js 2.23 kB
packages/icon/dist/umd/Secondary.js 1.79 kB
packages/icon/dist/umd/Serverless.js 1.75 kB
packages/icon/dist/umd/Settings.js 2.17 kB
packages/icon/dist/umd/ShardedCluster.js 2.12 kB
packages/icon/dist/umd/Shell.js 1.67 kB
packages/icon/dist/umd/Shield.js 2.1 kB
packages/icon/dist/umd/Shirt.js 1.61 kB
packages/icon/dist/umd/Shortcut.js 2.18 kB
packages/icon/dist/umd/SMS.js 1.61 kB
packages/icon/dist/umd/SortAscending.js 1.7 kB
packages/icon/dist/umd/SortDescending.js 1.69 kB
packages/icon/dist/umd/Sparkle.js 2.03 kB
packages/icon/dist/umd/SplitHorizontal.js 1.47 kB
packages/icon/dist/umd/SplitVertical.js 1.46 kB
packages/icon/dist/umd/Stitch.js 1.5 kB
packages/icon/dist/umd/Stop.js 1.35 kB
packages/icon/dist/umd/Streaming.js 2.5 kB
packages/icon/dist/umd/String.js 1.61 kB
packages/icon/dist/umd/Sun.js 1.82 kB
packages/icon/dist/umd/Support.js 1.7 kB
packages/icon/dist/umd/Sweep.js 1.72 kB
packages/icon/dist/umd/Table.js 1.49 kB
packages/icon/dist/umd/Tag.js 1.53 kB
packages/icon/dist/umd/TemporaryTable.js 1.73 kB
packages/icon/dist/umd/ThumbsDown.js 1.82 kB
packages/icon/dist/umd/ThumbsUp.js 1.81 kB
packages/icon/dist/umd/TimeSeries.js 1.86 kB
packages/icon/dist/umd/TimeSeriesCollection.js 2 kB
packages/icon/dist/umd/Trash.js 1.52 kB
packages/icon/dist/umd/Undo.js 1.83 kB
packages/icon/dist/umd/University.js 2.03 kB
packages/icon/dist/umd/Unlock.js 1.71 kB
packages/icon/dist/umd/Unsorted.js 1.75 kB
packages/icon/dist/umd/UpDownCarets.js 1.59 kB
packages/icon/dist/umd/Upload.js 1.8 kB
packages/icon/dist/umd/VerticalEllipsis.js 1.51 kB
packages/icon/dist/umd/View.js 1.65 kB
packages/icon/dist/umd/Visibility.js 1.82 kB
packages/icon/dist/umd/VisibilityOff.js 2.23 kB
packages/icon/dist/umd/Warning.js 1.59 kB
packages/icon/dist/umd/Wizard.js 1.94 kB
packages/icon/dist/umd/Wrench.js 1.93 kB
packages/icon/dist/umd/Write.js 2.21 kB
packages/icon/dist/umd/X.js 1.63 kB
packages/icon/dist/umd/XWithCircle.js 1.57 kB
packages/info-sprinkle/dist/esm/index.js 1.83 kB
packages/info-sprinkle/dist/umd/index.js 2.04 kB
packages/inline-definition/dist/esm/index.js 1.71 kB
packages/inline-definition/dist/umd/index.js 1.89 kB
packages/input-option/dist/esm/index.js 2.67 kB
packages/input-option/dist/umd/index.js 2.82 kB
packages/leafygreen-provider/dist/esm/index.js 1.87 kB
packages/leafygreen-provider/dist/umd/index.js 2.03 kB
packages/lib/dist/esm/index.js 3.27 kB
packages/lib/dist/umd/index.js 3.42 kB
packages/loading-indicator/dist/esm/index.js 3.69 kB
packages/loading-indicator/dist/esm/page-loader/index.js 2.85 kB
packages/loading-indicator/dist/esm/spinner/index.js 1.9 kB
packages/loading-indicator/dist/esm/testing/index.js 316 B
packages/loading-indicator/dist/umd/index.js 3.86 kB
packages/loading-indicator/dist/umd/testing/index.js 441 B
packages/logo/dist/esm/index.js 39 kB
packages/logo/dist/umd/index.js 39.4 kB
packages/marketing-modal/dist/esm/index.js 3.55 kB
packages/marketing-modal/dist/umd/index.js 3.75 kB
packages/menu/dist/esm/index.js 8.22 kB
packages/menu/dist/umd/index.js 8.48 kB
packages/modal/dist/esm/index.js 3.41 kB
packages/modal/dist/umd/index.js 3.56 kB
packages/number-input/dist/esm/index.js 5.68 kB
packages/number-input/dist/umd/index.js 5.87 kB
packages/ordered-list/dist/esm/index.js 1.33 kB
packages/ordered-list/dist/umd/index.js 1.5 kB
packages/pagination/dist/esm/index.js 1.69 kB
packages/pagination/dist/umd/index.js 1.94 kB
packages/palette/dist/esm/index.js 411 B
packages/palette/dist/umd/index.js 561 B
packages/password-input/dist/esm/index.js 4.54 kB
packages/password-input/dist/umd/index.js 4.76 kB
packages/pipeline/dist/esm/index.js 7.85 kB
packages/pipeline/dist/umd/index.js 8.12 kB
packages/polymorphic/dist/esm/index.js 1.27 kB
packages/polymorphic/dist/umd/index.js 1.41 kB
packages/popover/dist/esm/index.js 4.98 kB
packages/popover/dist/umd/index.js 5.15 kB
packages/portal/dist/esm/index.js 923 B
packages/portal/dist/umd/index.js 1.09 kB
packages/preview-card/dist/esm/index.js 2.35 kB
packages/preview-card/dist/esm/testing/index.js 2.67 kB
packages/preview-card/dist/umd/index.js 2.5 kB
packages/preview-card/dist/umd/testing/index.js 2.82 kB
packages/progress-bar/dist/esm/index.js 5.55 kB
packages/progress-bar/dist/esm/testing/index.js 507 B
packages/progress-bar/dist/umd/index.js 5.8 kB
packages/progress-bar/dist/umd/testing/index.js 635 B
packages/radio-box-group/dist/esm/index.js 2.87 kB
packages/radio-box-group/dist/umd/index.js 3 kB
packages/radio-group/dist/esm/index.js 3.25 kB
packages/radio-group/dist/umd/index.js 3.4 kB
packages/resizable/dist/esm/index.js 2.48 kB
packages/resizable/dist/umd/index.js 2.58 kB
packages/ripple/dist/esm/index.js 954 B
packages/ripple/dist/umd/index.js 1.05 kB
packages/search-input/dist/esm/index.js 5.9 kB
packages/search-input/dist/umd/index.js 6.12 kB
packages/section-nav/dist/esm/index.js 2.62 kB
packages/section-nav/dist/esm/testing/index.js 2.85 kB
packages/section-nav/dist/umd/index.js 2.77 kB
packages/section-nav/dist/umd/testing/index.js 3.03 kB
packages/segmented-control/dist/esm/index.js 5.44 kB
packages/segmented-control/dist/umd/index.js 5.59 kB
packages/select/dist/esm/index.js 8.69 kB
packages/select/dist/esm/testing/index.js 698 B
packages/select/dist/umd/index.js 8.9 kB
packages/select/dist/umd/testing/index.js 838 B
packages/side-nav/dist/esm/index.js 7.47 kB
packages/side-nav/dist/umd/index.js 7.73 kB
packages/skeleton-loader/dist/esm/index.js 3.19 kB
packages/skeleton-loader/dist/umd/index.js 3.4 kB
packages/split-button/dist/esm/index.js 3.56 kB
packages/split-button/dist/umd/index.js 3.72 kB
packages/stepper/dist/esm/index.js 3.48 kB
packages/stepper/dist/umd/index.js 3.69 kB
packages/table/dist/esm/index.js 8.14 kB
packages/table/dist/esm/testing/index.js 694 B
packages/table/dist/umd/index.js 8.41 kB
packages/table/dist/umd/testing/index.js 814 B
packages/tabs/dist/esm/index.js 5.14 kB
packages/tabs/dist/esm/testing/index.js 597 B
packages/tabs/dist/umd/index.js 5.29 kB
packages/tabs/dist/umd/testing/index.js 717 B
packages/testing-lib/dist/esm/index.js 3.34 kB
packages/testing-lib/dist/umd/index.js 3.56 kB
packages/testing-lib/dist/umd/renderHookServer17.js 385 B
packages/testing-lib/dist/umd/renderHookServer18.js 593 B
packages/text-area/dist/esm/index.js 2.2 kB
packages/text-area/dist/esm/testing/index.js 466 B
packages/text-area/dist/umd/index.js 2.36 kB
packages/text-area/dist/umd/testing/index.js 604 B
packages/text-input/dist/esm/index.js 2.5 kB
packages/text-input/dist/esm/testing/index.js 463 B
packages/text-input/dist/umd/index.js 2.68 kB
packages/text-input/dist/umd/testing/index.js 600 B
packages/toast/dist/esm/index.js 8.23 kB
packages/toast/dist/umd/index.js 8.53 kB
packages/toggle/dist/esm/index.js 3 kB
packages/toggle/dist/esm/testing/index.js 276 B
packages/toggle/dist/umd/index.js 3.19 kB
packages/toggle/dist/umd/testing/index.js 407 B
packages/tokens/dist/esm/index.js 2.83 kB
packages/tokens/dist/umd/index.js 2.94 kB
packages/toolbar/dist/esm/index.js 3.26 kB
packages/toolbar/dist/esm/testing/index.js 527 B
packages/toolbar/dist/umd/index.js 3.4 kB
packages/toolbar/dist/umd/testing/index.js 643 B
packages/tooltip/dist/esm/index.js 4.35 kB
packages/tooltip/dist/umd/index.js 4.63 kB
packages/typography/dist/esm/index.js 5.81 kB
packages/typography/dist/umd/index.js 5.96 kB
packages/vertical-stepper/dist/esm/index.js 3.19 kB
packages/vertical-stepper/dist/umd/index.js 3.39 kB
tools/build/dist/esm/index.js 6.3 kB
tools/build/dist/umd/cli.js 6.64 kB
tools/build/dist/umd/index.js 6.58 kB
tools/cli/dist/esm/index.js 2.33 kB
tools/cli/dist/umd/index.js 2.5 kB
tools/codemods/dist/_virtual/_rollupPluginBabelHelpers.js 936 B
tools/codemods/dist/codemods/modal-v20/transform.js 727 B
tools/codemods/dist/codemods/named-exports/transform.js 764 B
tools/codemods/dist/codemods/popover-v12/transform.js 1.1 kB
tools/codemods/dist/codemods/tabs-v17/transform.js 368 B
tools/codemods/dist/constants.js 148 B
tools/codemods/dist/esm/_virtual/_rollupPluginBabelHelpers.mjs 928 B
tools/codemods/dist/esm/codemods/modal-v20/transform.mjs 731 B
tools/codemods/dist/esm/codemods/named-exports/transform.mjs 751 B
tools/codemods/dist/esm/codemods/popover-v12/transform.mjs 1.09 kB
tools/codemods/dist/esm/codemods/tabs-v17/transform.mjs 366 B
tools/codemods/dist/esm/constants.mjs 148 B
tools/codemods/dist/esm/index.js 3.4 kB
tools/codemods/dist/esm/types.mjs 765 B
tools/codemods/dist/esm/utils/imports/getImportSpecifiersForDeclaration.mjs 280 B
tools/codemods/dist/esm/utils/imports/hasNamedImport.mjs 179 B
tools/codemods/dist/esm/utils/imports/mergeImportSpecifiers.mjs 261 B
tools/codemods/dist/esm/utils/jsx/getJSXAttributes.mjs 160 B
tools/codemods/dist/esm/utils/jsx/insertJSXComment/insertJSXComment.mjs 369 B
tools/codemods/dist/esm/utils/transformations/addJSXAttributes/addJSXAttributes.mjs 412 B
tools/codemods/dist/esm/utils/transformations/consolidateJSXAttributes/consolidateJSXAttributes.mjs 665 B
tools/codemods/dist/esm/utils/transformations/removeJSXAttributes/removeJSXAttributes.mjs 360 B
tools/codemods/dist/esm/utils/transformations/replaceJSXAttributes/replaceJSXAttributes.mjs 278 B
tools/codemods/dist/types.js 765 B
tools/codemods/dist/umd/index.js 3.64 kB
tools/codemods/dist/utils/imports/getImportSpecifiersForDeclaration.js 283 B
tools/codemods/dist/utils/imports/hasNamedImport.js 183 B
tools/codemods/dist/utils/imports/mergeImportSpecifiers.js 260 B
tools/codemods/dist/utils/jsx/getJSXAttributes.js 164 B
tools/codemods/dist/utils/jsx/insertJSXComment/insertJSXComment.js 371 B
tools/codemods/dist/utils/transformations/addJSXAttributes/addJSXAttributes.js 410 B
tools/codemods/dist/utils/transformations/consolidateJSXAttributes/consolidateJSXAttributes.js 664 B
tools/codemods/dist/utils/transformations/removeJSXAttributes/removeJSXAttributes.js 364 B
tools/codemods/dist/utils/transformations/replaceJSXAttributes/replaceJSXAttributes.js 282 B
tools/create/dist/esm/index.js 4.17 kB
tools/create/dist/umd/index.js 4.34 kB
tools/eslint-plugin/dist/esm/index.js 1.08 kB
tools/eslint-plugin/dist/umd/index.js 1.18 kB
tools/install/dist/esm/index.js 2.2 kB
tools/install/dist/umd/index.js 2.36 kB
tools/link/dist/esm/index.js 3.79 kB
tools/link/dist/umd/index.js 3.91 kB
tools/lint/dist/esm/index.js 4.11 kB
tools/lint/dist/umd/index.js 4.25 kB
tools/meta/dist/esm/index.js 1.71 kB
tools/meta/dist/umd/index.js 1.85 kB
tools/prompt-kit/dist/esm/index.js 2.27 kB
tools/prompt-kit/dist/umd/index.js 2.41 kB
tools/slackbot/dist/esm/index.js 4.8 kB
tools/slackbot/dist/umd/index.js 4.97 kB
tools/storybook-addon/dist/esm/index.js 2.22 kB
tools/storybook-addon/dist/esm/main.js 2.22 kB
tools/storybook-addon/dist/esm/manager.js 554 B
tools/storybook-addon/dist/esm/preview.js 1.69 kB
tools/storybook-addon/dist/umd/index.js 2.34 kB
tools/storybook-addon/dist/umd/main.js 2.34 kB
tools/storybook-addon/dist/umd/manager.js 691 B
tools/storybook-addon/dist/umd/preview.js 1.81 kB
tools/storybook-decorators/dist/esm/index.js 3.28 kB
tools/storybook-decorators/dist/umd/index.js 3.57 kB
tools/storybook-utils/dist/esm/index.js 2.77 kB
tools/storybook-utils/dist/umd/index.js 2.9 kB
tools/test-harnesses/dist/esm/index.js 1.78 kB
tools/test-harnesses/dist/umd/index.js 1.91 kB
tools/test/dist/esm/index.js 1.68 kB
tools/test/dist/umd/index.js 1.82 kB
tools/update/dist/esm/index.js 725 B
tools/update/dist/umd/index.js 893 B
tools/validate/dist/esm/index.js 5.75 kB
tools/validate/dist/umd/index.js 5.98 kB

compressed-size-action

@shaneeza shaneeza closed this Oct 8, 2025
@shaneeza shaneeza reopened this Oct 16, 2025
@shaneeza shaneeza requested a review from Copilot October 16, 2025 20:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

} else {
// If the previously focused element is no longer in the DOM, focus the body
// This mimics the behavior of the native HTML Dialog element
document.body.focus();
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

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

[nitpick] Falling back to document.body.focus() may fail because body is not guaranteed to be focusable, leaving keyboard users without a clear focus target. Consider ensuring the fallback element is explicitly focusable (e.g., adding tabIndex='-1' to body or selecting another stable focusable ancestor) or skipping the fallback to avoid a failed focus call.

Suggested change
document.body.focus();
const body = document.body;
const hadTabIndex = body.hasAttribute('tabIndex');
if (!hadTabIndex) {
body.setAttribute('tabIndex', '-1');
}
body.focus();
if (!hadTabIndex) {
body.removeAttribute('tabIndex');
}

Copilot uses AI. Check for mistakes.
const isAriaVisible = element.getAttribute('aria-hidden') === 'false';
const { display, opacity, visibility } = window.getComputedStyle(element);

const isCSSVisible =
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm removing this check because Drawer no longer updates these properties directly in the component, meaning the values were always the same regardless of whether the drawer was open or closed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

noted, is there something else we should check in addition to the aria attribute?

@shaneeza shaneeza marked this pull request as ready for review October 16, 2025 21:38
@shaneeza shaneeza requested a review from a team as a code owner October 16, 2025 21:38
@shaneeza shaneeza requested review from stephl3 and removed request for a team October 16, 2025 21:38
});
};

// Reusable play function for testing focus management with toolbar buttons
Copy link
Collaborator

Choose a reason for hiding this comment

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

looks like there is a flaky snapshot because it's taking before animations/repositioning completes. can we add snapshot delays to ensure UI is stable before capturing? https://www.chromatic.com/docs/delay/

closeButton: `${root}-close_button`,
scrollContainer: `${root}-scroll_container`,
toolbar: `${root}-toolbar`,
resizer: `${root}-resizer`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

curious what is the reason for including this in this PR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I can remove this. I thought I was going to end up needing it.

const isAriaVisible = element.getAttribute('aria-hidden') === 'false';
const { display, opacity, visibility } = window.getComputedStyle(element);

const isCSSVisible =
Copy link
Collaborator

Choose a reason for hiding this comment

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

noted, is there something else we should check in addition to the aria attribute?

Comment on lines +143 to +146
* Focuses the first focusable element in the drawer when the drawer is opened.
* Also handles restoring focus when the drawer is closed.
*
* This is only necessary for embedded drawers. Overlay drawers use the native focus behavior of the dialog element.
Copy link
Collaborator

Choose a reason for hiding this comment

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

queryFirstFocusableElement has a set list of focusable selectors it considers and "the native focus behavior of the dialog element" is to look for children with the autofocus attribute. However, these don't actually cover all cases that consumers may want to focus, such as a code editor.

After receiving feedback about this use case, it led to this change reintroducing the initialFocus prop in Modal. We don't use Modal and Drawer in all the same ways, but seeing this change makes me think they should follow the same focus management pattern. We may be able to use a similar method as focusModalChildElement for the first part of this effect

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I like this pattern. However, I think if we go with this approach, then we might have to override the default dialog behavior since initialFocus does not work by default.

So the pattern would be in a native dialog and the embedded div:

  1. Drawer opens
  2. We check the initialFocus prop
    a) if auto, we find the autofocus attribute or the first focusable item
    b) if provided, we focus that provided element
    c) if null, we don't focus anything

We'll end up losing the native dialog focus management this way, but it does become more customizable.

However, I am curious about the modal focus management. Why do we need a ref option when you can add autofocus to the element?

Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the native dialog focus management you're concerned about losing? In Modal, initialFocus is mostly additive and doesn't conflict

autofocus can only be applied to the typical focusable elements but can't be used for something like a code editor. Although the initial implementation of Modal used a css selector like "#my-code-editor", I added a ref option because it's more type-safe and robust than a string

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What is the native dialog focus management you're concerned about losing?

Not necessarily losing, but having to re-implement it. I noticed here that if any child has autofocus, we let the browser focus it automatically, but we manually focus the first focusable element. So in this case, aren't we manually overriding the default behavior of finding the first focusable element and re-implementing it?

const autoFocusElement = modalElement.querySelector(
'[autofocus]',
) as HTMLElement;
if (autoFocusElement) {
// Don't need to explicitly call `focus` because the browser handles it
return autoFocusElement;
}
// Otherwise, focus first focusable element
const firstFocusableElement = queryFirstFocusableElement(modalElement);

autofocus can only be applied to the typical focusable elements but can't be used for something like a code editor. Although the initial implementation of Modal used a css selector like "#my-code-editor", I added a ref option because it's more type-safe and robust than a string

Thanks for clarifying.

Copy link
Collaborator

Choose a reason for hiding this comment

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

So in this case, aren't we manually overriding the default behavior of finding the first focusable element and re-implementing it?

focusModalChildElement is the logic we use to determine how a child element should be focused. The consumer has full control using either the initialFocus prop or the autoFocus attribute on a child element. If initialFocus is not specified and a child element does not have autoFocus specified, then we query for the first focusable element. Happy to huddle on this if further clarification is needed!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, actually would love to huddle on this, I'll Slack you

return;
}

// Restore focus when closing (only if we had handled focus during this session)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is starting to feel like a re-implementation of the <dialog> element's focus patterns. Is there an explicit ticket requesting this functionality? If so, I'm curious what do you think about using the <dialog> under the hood for displayMode="embedded"? Since we're using a non-modal <dialog> element, we already end up having to apply the overlay styles for displayMode="overlay". The benefit would be that we get focus management for free; trade-off is that we'd be incorrectly using a dialog element

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There was no ticket requesting this. I just observed that the embedded drawer was not accessible when it was opened. And you're correct, I tried to mimic the native dialog behavior. I like that if we use a non-modal dialog, then we get this behavior for free, but I don't know if using dialog incorrectly is worth it. We're trying to be more intentional, and this seems semantically incorrect. It's not really a dialog, and screen readers would announce it as a dialog as well.

Also, If we end up adding the same focus management as the modal, then we probably won't even be using the free focus management from dialog.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Curious, why do you consider using a dialog incorrect in this case? Is it because a dialog is supposed to float on top of content?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, my understanding is that a dialog is intended for modal or non-modal overlays. What makes the embedded drawer not accessible? I'm curious what determines focus jumping to the embedded drawer as accessible vs not doing that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My concern about the embedded drawer is that, when it is opened, the focus does not shift to the drawer. It's hard to find out what the correct accessibility behavior of the embedded drawer should be since this is a div and not a dialog. Since the overlay drawer is sitting on top of the content, it makes sense that the focus should automatically move to the drawer. For the embedded drawer, the drawer opens and shifts the content, but the focus remains on the trigger (if there is a trigger). The consumer would have to do a lot of tabbing to get to the drawer.

The research I've done on this hasn't been that helpful, but I still think I should do some more investigating before moving forward with this change.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see, this sounds like it may vary depending on product usage. Can we pull design in and maybe discuss usage with product engineers before applying to all cases?

Alternatively, we could put this behind a discriminated union prop and make this opt-in. i.e.

  • if overlay, rely on autoFocus being set (although this also may require initialFocus)
  • if embedded, check prop to determine focus management. Could see this working in a few ways; a couple ideas are:
    • default focus first focusable (breaking change)
    • default no focus (minor change) and allow users to specify "auto" which would focus first focusable or specify an element ref

@shaneeza shaneeza requested a review from stephl3 October 17, 2025 16:50
@shaneeza shaneeza marked this pull request as draft October 24, 2025 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants