Skip to content

chore: update upstream code #6

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

Merged
merged 28 commits into from
Apr 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f75223a
chore: Fix generated code sample for S2 TooltipTrigger docs (#8000)
LFDanLu Apr 3, 2025
148fcf1
fix: export SortDescriptor type from S2 (#8030)
ToyWalrus Apr 4, 2025
8ea86b7
Merge branch 'develop' of https://github.com/PSPDFKit-labs/react-spec…
ritz078 Apr 4, 2025
dd22a53
chore: Deprecate UNSTABLE_portalContainer in favor for PortalProvider…
LFDanLu Apr 7, 2025
cce6f16
feat: Add escapeKeyBehavior to GridList/ListBox/Menu/Table/Tree (#7974)
LFDanLu Apr 7, 2025
5e7a5af
fix: useMove broken by NODE_ENV check (#8046)
devongovett Apr 7, 2025
ad4681f
fix: ColorWheel track click (#8049)
snowystinger Apr 7, 2025
7e7e33d
fix: minor typo in CalendarDate docs (#8043)
DarkstarXDD Apr 8, 2025
8fbe17f
fix: Updating collection when items change parents (#8052)
devongovett Apr 8, 2025
4bcf541
export Autocomplete from S2 (#8050)
reidbarber Apr 8, 2025
2edef89
chore: Optimize table test performance (#8051)
devongovett Apr 8, 2025
fd7b5dd
chore: Update typescript to 5.8 (#7888)
snowystinger Apr 8, 2025
68c67d4
fix: Apply touch-action by default in usePress (#8047)
devongovett Apr 8, 2025
5dcf9ce
fix: set some better flex behaviour (#8048)
snowystinger Apr 8, 2025
a654a33
fix: Support React 19 and remove Jest reliance in test utils (#7686)
LFDanLu Apr 8, 2025
c81a23c
chore: revert ts update (#8060)
snowystinger Apr 8, 2025
04b9fe1
fix: add static color to s2 notification badge (#8055)
yihuiliao Apr 9, 2025
d93947e
chore: Latest translations (#8036)
rgeraghty Apr 9, 2025
77589c2
fix: Relax Parcel version range in public plugins (#8067)
devongovett Apr 9, 2025
12180a0
Disclosure button label size update to match new sizes from Specturm …
ktabors Apr 9, 2025
631eb85
chore: audit 3.41 (#8064)
snowystinger Apr 9, 2025
58d96ca
chore: audit 3.41 (#8064)
snowystinger Apr 9, 2025
921e1c2
Merge branch 'develop' of https://github.com/PSPDFKit-labs/react-spec…
ritz078 Apr 10, 2025
b509ed4
Merge branch 'main' of https://github.com/adobe/react-spectrum into r…
ritz078 Apr 10, 2025
b453490
chore: Update package dependencies for @react-aria/overlays and @reac…
ritz078 Apr 10, 2025
f926dd5
chore: Update import paths and dependencies for @react-aria-nutrient
ritz078 Apr 10, 2025
125e24e
chore: Update import paths in TableTests to use @react-aria-nutrient
ritz078 Apr 10, 2025
c97d574
fix: Add missing newline at end of test files
ritz078 Apr 10, 2025
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
"@tailwindcss/postcss": "^4.0.0",
"@testing-library/dom": "^10.1.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^15.0.7",
"@testing-library/react": "^16.0.0",
"@testing-library/user-event": "patch:@testing-library/user-event@npm%3A14.6.1#~/.yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch",
"@types/react": "npm:[email protected]",
"@types/react-dom": "npm:[email protected]",
Expand Down
4 changes: 2 additions & 2 deletions packages/@internationalized/date/docs/CalendarDate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ date.toString(); // '2022-02-03'

By default, `CalendarDate` uses the Gregorian calendar system, but many other calendar systems that are used around the world are supported, such as Hebrew, Indian, Islamic, Buddhist, Ethiopic, and more. A <TypeLink links={docs.links} type={docs.exports.Calendar} /> instance can be passed to the `CalendarDate` constructor to represent dates in that calendar system.

This example creates a date in the Buddhist calendar system, which is equivalent to April 4th, 2020 in the Gregorian calendar.
This example creates a date in the Buddhist calendar system, which is equivalent to April 30th, 2020 in the Gregorian calendar.

```tsx
import {BuddhistCalendar} from '@internationalized/date';
Expand All @@ -86,7 +86,7 @@ See the [Calendar](Calendar.html#implementations) docs for details about the sup

Many calendar systems have only one era, or a modern era and a pre-modern era (e.g. AD and BC in the Gregorian calendar). However, other calendar systems may have many eras. For example, the Japanese calendar has eras for the reign of each Emperor. `CalendarDate` represents eras using string identifiers, which can be passed as an additional parameter to the constructor before the year. When eras are present, years are numbered starting from 1 within the era.

This example creates a date in the Japanese calendar system, which is equivalent to April 4th, 2020 in the Gregorian calendar.
This example creates a date in the Japanese calendar system, which is equivalent to April 30th, 2019 in the Gregorian calendar.

```tsx
import {JapaneseCalendar} from '@internationalized/date';
Expand Down
10 changes: 6 additions & 4 deletions packages/@react-aria/collections/src/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,13 @@ export class Document<T, C extends BaseCollection<T> = BaseCollection<T>> extend
}

updateCollection(): void {
// First, update the indices of dirty element children.
// First, remove disconnected nodes and update the indices of dirty element children.
for (let element of this.dirtyNodes) {
element.updateChildIndices();
if (element instanceof ElementNode && (!element.isConnected || element.isHidden)) {
this.removeNode(element);
} else {
element.updateChildIndices();
}
}

// Next, update dirty collection nodes.
Expand All @@ -471,8 +475,6 @@ export class Document<T, C extends BaseCollection<T> = BaseCollection<T>> extend
if (element.isConnected && !element.isHidden) {
element.updateNode();
this.addNode(element);
} else {
this.removeNode(element);
}

element.isMutated = false;
Expand Down
17 changes: 14 additions & 3 deletions packages/@react-aria/grid/src/useGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,16 @@ export interface GridProps extends DOMProps, AriaLabelingProps {
/** Handler that is called when a user performs an action on the row. */
onRowAction?: (key: Key) => void,
/** Handler that is called when a user performs an action on the cell. */
onCellAction?: (key: Key) => void
onCellAction?: (key: Key) => void,
/**
* Whether pressing the escape key should clear selection in the grid or not.
*
* Most experiences should not modify this option as it eliminates a keyboard user's ability to
* easily clear selection. Only use if the escape key is being handled externally or should not
* trigger selection clearing contextually.
* @default 'clearSelection'
*/
escapeKeyBehavior?: 'clearSelection' | 'none'
}

export interface GridAria {
Expand All @@ -77,7 +86,8 @@ export function useGrid<T>(props: GridProps, state: GridState<T, GridCollection<
scrollRef,
getRowText,
onRowAction,
onCellAction
onCellAction,
escapeKeyBehavior = 'clearSelection'
} = props;
let {selectionManager: manager} = state;

Expand Down Expand Up @@ -106,7 +116,8 @@ export function useGrid<T>(props: GridProps, state: GridState<T, GridCollection<
keyboardDelegate: delegate,
isVirtualized,
scrollRef,
disallowTypeAhead
disallowTypeAhead,
escapeKeyBehavior
});

let id = useId(props.id);
Expand Down
17 changes: 14 additions & 3 deletions packages/@react-aria/gridlist/src/useGridList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,16 @@ export interface AriaGridListProps<T> extends GridListProps<T>, DOMProps, AriaLa
* via the left/right arrow keys or the tab key.
* @default 'arrow'
*/
keyboardNavigationBehavior?: 'arrow' | 'tab'
keyboardNavigationBehavior?: 'arrow' | 'tab',
/**
* Whether pressing the escape key should clear selection in the grid list or not.
*
* Most experiences should not modify this option as it eliminates a keyboard user's ability to
* easily clear selection. Only use if the escape key is being handled externally or should not
* trigger selection clearing contextually.
* @default 'clearSelection'
*/
escapeKeyBehavior?: 'clearSelection' | 'none'
}

export interface AriaGridListOptions<T> extends Omit<AriaGridListProps<T>, 'children'> {
Expand Down Expand Up @@ -105,7 +114,8 @@ export function useGridList<T>(props: AriaGridListOptions<T>, state: ListState<T
onAction,
disallowTypeAhead,
linkBehavior = 'action',
keyboardNavigationBehavior = 'arrow'
keyboardNavigationBehavior = 'arrow',
escapeKeyBehavior = 'clearSelection'
} = props;

if (!props['aria-label'] && !props['aria-labelledby']) {
Expand All @@ -124,7 +134,8 @@ export function useGridList<T>(props: AriaGridListOptions<T>, state: ListState<T
shouldFocusWrap: props.shouldFocusWrap,
linkBehavior,
disallowTypeAhead,
autoFocus: props.autoFocus
autoFocus: props.autoFocus,
escapeKeyBehavior
});

let id = useId(props.id);
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-aria/interactions/src/useMove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export function useMove(props: MoveEvents): MoveResult {
state.current.didMove = false;
};

if (typeof PointerEvent === 'undefined') {
if (typeof PointerEvent === 'undefined' && process.env.NODE_ENV === 'test') {
let onMouseMove = (e: MouseEvent) => {
if (e.button === 0) {
move(e, 'mouse', e.pageX - (state.current.lastPosition?.pageX ?? 0), e.pageY - (state.current.lastPosition?.pageY ?? 0));
Expand Down Expand Up @@ -151,7 +151,7 @@ export function useMove(props: MoveEvents): MoveResult {
addGlobalListener(window, 'touchend', onTouchEnd, false);
addGlobalListener(window, 'touchcancel', onTouchEnd, false);
};
} else if (process.env.NODE_ENV === 'test') {
} else {
let onPointerMove = (e: PointerEvent) => {
if (e.pointerId === state.current.id) {
let pointerType = (e.pointerType || 'mouse') as PointerType;
Expand Down
20 changes: 16 additions & 4 deletions packages/@react-aria/interactions/src/usePress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ export function usePress(props: PressHookProps): PressResult {
preventFocusOnPress,
shouldCancelOnPointerExit,
allowTextSelectionOnPress,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
ref: _, // Removing `ref` from `domProps` because TypeScript is dumb
ref: domRef,
...domProps
} = usePressResponderContext(props);

Expand Down Expand Up @@ -814,13 +813,26 @@ export function usePress(props: PressHookProps): PressResult {
triggerSyntheticClick
]);

// Remove user-select: none in case component unmounts immediately after pressStart
// Avoid onClick delay for double tap to zoom by default.
useEffect(() => {
let element = domRef?.current;
if (element && (element instanceof getOwnerWindow(element).Element)) {
// Only apply touch-action if not already set by another CSS rule.
let style = getOwnerWindow(element).getComputedStyle(element);
if (style.touchAction === 'auto') {
// touchAction: 'manipulation' is supposed to be equivalent, but in
// Safari it causes onPointerCancel not to fire on scroll.
// https://bugs.webkit.org/show_bug.cgi?id=240917
(element as HTMLElement).style.touchAction = 'pan-x pan-y pinch-zoom';
}
}
}, [domRef]);

// Remove user-select: none in case component unmounts immediately after pressStart
useEffect(() => {
let state = ref.current;
return () => {
if (!allowTextSelectionOnPress) {

restoreTextSelection(state.target ?? undefined);
}
for (let dispose of state.disposables) {
Expand Down
69 changes: 68 additions & 1 deletion packages/@react-aria/interactions/stories/usePress.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
Modal,
ModalOverlay
} from 'react-aria-components';
import React from 'react';
import React, {useState} from 'react';
import styles from './usePress-stories.css';
import {usePress} from '@react-aria-nutrient/interactions';

Expand Down Expand Up @@ -234,3 +234,70 @@ export function SoftwareKeyboardIssue() {
</div>
);
}

export function AndroidUnmountIssue() {
let [showButton, setShowButton] = useState(true);

return (
<div style={{display: 'flex', flexDirection: 'column', alignItems: 'center'}}>
<p>This story tests an Android issue where tapping a button that unmounts causes the element behind it to receive onClick.</p>
<div style={{position: 'relative', width: 100, height: 100}}>
<button
type="button"
onClick={() => {
alert('button underneath was pressed');
}}
style={{position: 'absolute', top: 0}}>
Test 2
</button>
{showButton && (
<Button
className="foo"
style={{position: 'absolute', top: 0}}
onPress={() => {
console.log('ra Button pressed');
setShowButton(false);
}}>
Test
</Button>
)}
</div>
</div>
);
}

export function IOSScrollIssue() {
return (
<div style={{display: 'flex', flexDirection: 'column', alignItems: 'center'}}>
<p>This story tests an iOS Safari issue that causes onPointerCancel not to be fired with touch-action: manipulation. Scrolling the list should not trigger onPress.</p>
<div
style={{
marginTop: 10,
width: 500,
height: 100,
overflowY: 'hidden',
overflowX: 'auto',
border: '1px solid black',
display: 'flex',
gap: 8
}}>
{Array.from({length: 10}).map((_, i) => (
<Card key={i} />
))}
</div>
</div>
);
}

function Card() {
return (
<Button
className="foo"
style={{height: 80, width: 150, flexShrink: 0}}
onPress={() => {
alert('pressed');
}}>
Test
</Button>
);
}
Loading