Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/fling-over-page-keeps-layer-open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@astryxdesign/core': patch
---

[fix] A pan over the page that the browser doesn't take as a scroll no longer closes an open popover or selector list, and no longer taps the page element under the finger.

@cixzhang
61 changes: 61 additions & 0 deletions apps/storybook/stories/Popover.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {BottomSheet} from '@astryxdesign/core/BottomSheet';
import {Popover} from '@astryxdesign/core/Popover';
import type {PopoverTriggerRenderProps} from '@astryxdesign/core/Popover';
import {Button} from '@astryxdesign/core/Button';
import {ResizeHandle, useResizable} from '@astryxdesign/core/Resizable';
import {Token} from '@astryxdesign/core/Token';
import {Link} from '@astryxdesign/core/Link';
import {List, ListItem} from '@astryxdesign/core/List';
Expand Down Expand Up @@ -344,6 +345,66 @@ export const Default: Story = {
},
};

function ResizablePanel() {
const resizable = useResizable({defaultSize: 120, minSize: 60, maxSize: 320});
return (
<div style={{display: 'flex', blockSize: 64}}>
<section
aria-label="Resizable panel"
style={{inlineSize: resizable.size, overflow: 'hidden'}}>
<Text>{resizable.size}px</Text>
</section>
<ResizeHandle
direction="horizontal"
hasDivider
resizable={resizable}
label="Resize panel"
/>
</div>
);
}

/**
* An open Popover above page controls that take a finger's drag: a resize
* handle and rows with swipe actions. On a touch screen each follows the
* finger while the Popover is open.
*/
export const OverPageControls: Story = {
tags: ['!autodocs'],
render: () => (
<VStack gap={4}>
<Popover
placement="below"
label="Settings"
width={240}
content={<Text>Popover content</Text>}>
<Button label="Settings">Settings</Button>
</Popover>
<div style={{blockSize: 120}} />
<ResizablePanel />
<List>
{['Message 1', 'Message 2', 'Message 3'].map(label => (
<ListItem
key={label}
label={label}
onClick={() => {}}
swipeActions={{
trailing: [
{label: 'Archive', onActivate: () => {}, variant: 'neutral'},
{
label: 'Delete',
onActivate: () => {},
variant: 'destructive',
},
],
}}
/>
))}
</List>
</VStack>
),
};

// =============================================================================
// Filter Panel
// =============================================================================
Expand Down
54 changes: 32 additions & 22 deletions docs/architecture/layer-runtime.md

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions packages/core/src/Breadcrumbs/BreadcrumbItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import type {BaseProps} from '../BaseProps';
import {themeProps} from '../utils/themeProps';
import {focusOutlineProps} from '../utils/focusOutline.stylex';
import {Icon} from '../Icon';
import {usePopover} from '../Popover/usePopover';
import {usePopoverInternal} from '../Popover/usePopover';
import {useListFocus} from '../hooks/useListFocus';
import {useMenuPress} from '../hooks/useMenuPress';
import {pressOnItemsOnly} from '../hooks/menuPressOnItems';
Expand Down Expand Up @@ -552,7 +552,9 @@ function BreadcrumbMenuTrigger({
// to activate the tracking they read, so it activates it itself.
const {ref: modalityRef} = useInteractionModalityTracking();

const popover = usePopover({
const popover = usePopoverInternal({
// The menu, not the layer, owns what a touch outside that pans does.
ownsOutsidePan: true,
hasLightDismiss: true,
hasCloseButton: false,
hasAutoFocus: false,
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/DropdownMenu/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import React, {
} from 'react';
import {readAccessibleName} from '../utils/accessibleName';
import * as stylex from '@stylexjs/stylex';
import {usePopover} from '../Popover/usePopover';
import {usePopoverInternal} from '../Popover/usePopover';
import {holdEntranceInput} from '../Layer/holdEntranceInput';
import {
claimPress,
Expand Down Expand Up @@ -1108,10 +1108,12 @@ function DropdownMenuPopover({
? button.label
: undefined;

const popover = usePopover({
const popover = usePopoverInternal({
onHide: handleLayerHide,
onShow: handleLayerShow,
hasLightDismiss: true,
// The menu, not the layer, owns what a touch outside that pans does.
ownsOutsidePan: true,
hasCloseButton: false,
hasAutoFocus: false,
// Without a header or footer the popup's own role="menu" is the exposed
Expand Down
Loading
Loading