Skip to content

Commit 46a0046

Browse files
committed
Merge branch 'main' into ts-strict-update-react-aria-b
# Conflicts: # packages/@react-aria/listbox/src/useOption.ts
2 parents 76483d0 + 52ce139 commit 46a0046

38 files changed

+4646
-318
lines changed

.eslintrc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module.exports = {
3131
'jsdoc/require-description-complete-sentence': [ERROR, {abbreviations: ['e.g', 'i.e']}],
3232
'jsdoc/check-alignment': ERROR,
3333
'jsdoc/check-indentation': ERROR,
34-
'jsdoc/check-tag-names': [ERROR, {definedTags: ['selector']}],
34+
'jsdoc/check-tag-names': [ERROR, {definedTags: ['selector', 'note']}],
3535
// enable this rule to see literally everything missing jsdocs, this rule needs some refinement but is good as a sanity check.
3636
// 'jsdoc/require-jsdoc': [ERROR, {contexts:['TSInterfaceDeclaration TSPropertySignature', 'TSInterfaceDeclaration TSMethodSignature']}],
3737
'jsdoc/require-description': [ERROR, {exemptedBy: ['deprecated'], checkConstructors: false}],

packages/@react-aria/grid/src/useGridCell.ts

+15
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,21 @@ export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps
240240
gridCellProps['aria-colindex'] = (node.colIndex ?? node.index) + 1; // aria-colindex is 1-based
241241
}
242242

243+
// When pressing with a pointer and cell selection is not enabled, usePress will be applied to the
244+
// row rather than the cell. However, when the row is draggable, usePress cannot preventDefault
245+
// on pointer down, so the browser will try to focus the cell which has a tabIndex applied.
246+
// To avoid this, remove the tabIndex from the cell briefly on pointer down.
247+
if (shouldSelectOnPressUp && gridCellProps.tabIndex != null && gridCellProps.onPointerDown == null) {
248+
gridCellProps.onPointerDown = (e) => {
249+
let el = e.currentTarget;
250+
let tabindex = el.getAttribute('tabindex');
251+
el.removeAttribute('tabindex');
252+
requestAnimationFrame(() => {
253+
el.setAttribute('tabindex', tabindex);
254+
});
255+
};
256+
}
257+
243258
return {
244259
gridCellProps,
245260
isPressed

packages/@react-aria/listbox/docs/useListBox.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ function Example() {
251251
<Item key="egg">Egg Salad</Item>
252252
<Item key="ham">Ham</Item>
253253
</ListBox>
254-
<p>Current selection (controlled): {[...selected].join(', ')}</p>
254+
<p>Current selection (controlled): {selected === 'all' ? 'all' : [...selected].join(', ')}</p>
255255
</>
256256
);
257257
}

packages/@react-aria/listbox/src/useOption.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ export interface OptionAria extends SelectableItemStates {
3030
descriptionProps: DOMAttributes,
3131

3232
/** Whether the option is currently focused. */
33-
isFocused: boolean
33+
isFocused: boolean,
34+
35+
/** Whether the option is keyboard focused. */
36+
isFocusVisible: boolean
3437
}
3538

3639
export interface AriaOptionProps {
@@ -92,7 +95,6 @@ export function useOption<T>(props: AriaOptionProps, state: ListState<T>, ref: R
9295

9396
let isDisabled = props.isDisabled ?? state.disabledKeys.has(key);
9497
let isSelected = props.isSelected ?? state.selectionManager.isSelected(key);
95-
let isFocused = state.selectionManager.focusedKey === key;
9698
let shouldSelectOnPressUp = props.shouldSelectOnPressUp ?? data?.shouldSelectOnPressUp;
9799
let shouldFocusOnHover = props.shouldFocusOnHover ?? data?.shouldFocusOnHover;
98100
let shouldUseVirtualFocus = props.shouldUseVirtualFocus ?? data?.shouldUseVirtualFocus;
@@ -122,7 +124,7 @@ export function useOption<T>(props: AriaOptionProps, state: ListState<T>, ref: R
122124
optionProps['aria-setsize'] = getItemCount(state.collection);
123125
}
124126

125-
let {itemProps, isPressed, hasAction, allowsSelection} = useSelectableItem({
127+
let {itemProps, isPressed, isFocused, hasAction, allowsSelection} = useSelectableItem({
126128
selectionManager: state.selectionManager,
127129
key,
128130
ref,
@@ -157,6 +159,7 @@ export function useOption<T>(props: AriaOptionProps, state: ListState<T>, ref: R
157159
id: descriptionId
158160
},
159161
isFocused,
162+
isFocusVisible: isFocused && isFocusVisible(),
160163
isSelected,
161164
isDisabled,
162165
isPressed,

packages/@react-aria/menu/docs/useMenu.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ function Example() {
366366
<Item key='tools'>Tools</Item>
367367
<Item key='console'>Console</Item>
368368
</MenuButton>
369-
<p>Current selection (controlled): {[...selected].join(', ')}</p>
369+
<p>Current selection (controlled): {selected === 'all' ? 'all' : [...selected].join(', ')}</p>
370370
</>
371371
);
372372
}

packages/@react-aria/table/src/useTableCell.ts

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export interface AriaTableCellProps {
2222
node: GridNode<unknown>,
2323
/** Whether the cell is contained in a virtual scroller. */
2424
isVirtualized?: boolean,
25+
/** Whether selection should occur on press up instead of press down. */
26+
shouldSelectOnPressUp?: boolean,
2527
/**
2628
* Handler that is called when a user performs an action on the cell.
2729
* Please use onCellAction at the collection level instead.

packages/@react-spectrum/menu/docs/Menu.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ function Example() {
167167
<Item key='Console'>Console</Item>
168168
</Menu>
169169
</MenuTrigger>
170-
<p>Current selection (controlled): {[...selected].join(', ')}</p>
170+
<p>Current selection (controlled): {selected === 'all' ? 'all' : [...selected].join(', ')}</p>
171171
</>
172172
);
173173
}

packages/@react-spectrum/numberfield/test/NumberField.test.js

+7-10
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ describe('NumberField', function () {
882882
textField.setSelectionRange(2, 3);
883883
userEvent.type(textField, '{backspace}');
884884
expect(announce).toHaveBeenCalledTimes(2);
885-
expect(announce).toHaveBeenLastCalledWith('−$.00', 'assertive');
885+
expect(announce).toHaveBeenLastCalledWith('−$0.00', 'assertive');
886886
textField.setSelectionRange(2, 2);
887887
typeText(textField, '1');
888888
expect(announce).toHaveBeenCalledTimes(3);
@@ -902,7 +902,7 @@ describe('NumberField', function () {
902902
userEvent.type(textField, '{backspace}');
903903
expect(textField).toHaveAttribute('value', '($18.00');
904904
expect(announce).toHaveBeenCalledTimes(5);
905-
expect(announce).toHaveBeenLastCalledWith('($18.00', 'assertive');
905+
expect(announce).toHaveBeenLastCalledWith('$18.00', 'assertive');
906906
act(() => {textField.blur();});
907907
expect(textField).toHaveAttribute('value', '$18.00');
908908
expect(onChangeSpy).toHaveBeenCalledTimes(3);
@@ -914,9 +914,8 @@ describe('NumberField', function () {
914914
expect(announce).toHaveBeenLastCalledWith('Empty', 'assertive');
915915
typeText(textField, '($32)');
916916
expect(textField).toHaveAttribute('value', '($32)');
917-
expect(announce).toHaveBeenCalledTimes(11);
918-
console.log(announce.mock.calls[4]);
919-
expect(announce).toHaveBeenLastCalledWith('−$32', 'assertive');
917+
expect(announce).toHaveBeenCalledTimes(9);
918+
expect(announce).toHaveBeenLastCalledWith('−$32.00', 'assertive');
920919
act(() => {textField.blur();});
921920
expect(textField).toHaveAttribute('value', '($32.00)');
922921
expect(onChangeSpy).toHaveBeenCalledTimes(4);
@@ -932,17 +931,15 @@ describe('NumberField', function () {
932931
act(() => {textField.focus();});
933932
userEvent.type(textField, '(10)');
934933
expect(textField).toHaveAttribute('value', '(10)');
935-
expect(announce).toHaveBeenCalledTimes(4);
936-
expect(announce).toHaveBeenLastCalledWith('−10', 'assertive');
937-
expect(announce).toHaveBeenCalledTimes(4);
938-
expect(announce).toHaveBeenLastCalledWith('−10', 'assertive');
934+
expect(announce).toHaveBeenCalledTimes(3);
935+
expect(announce).toHaveBeenLastCalledWith('؜−١٠٫٠٠ US$', 'assertive');
939936
act(() => {textField.blur();});
940937
expect(textField).toHaveAttribute('value', '(US$10.00)');
941938
expect(onChangeSpy).toHaveBeenCalledTimes(1);
942939
expect(onChangeSpy).toHaveBeenLastCalledWith(-10);
943940
});
944941

945-
it.only.each`
942+
it.each`
946943
Name
947944
${'NumberField'}
948945
`('$Name can edit a currencySign accounting in a locale that does not use the parenthesis notation', () => {

packages/@spectrum-icons/workflow/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"make-icons": "babel-node --extensions '.cjs,.js' --presets @babel/env ./scripts/generateIcons.cjs -i '[]' && yarn generate-types"
2323
},
2424
"dependencies": {
25-
"@adobe/react-spectrum-workflow": "2.3.3",
25+
"@adobe/react-spectrum-workflow": "2.3.4",
2626
"@react-spectrum/icon": "^3.7.0",
2727
"@swc/helpers": "^0.4.14"
2828
},

packages/dev/docs/src/Layout.js

+8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ const mdxComponents = {
7272
</span>
7373
</h3>
7474
),
75+
h4: ({children, ...props}) => (
76+
<h4 {...props} className={clsx(typographyStyles['spectrum-Heading5'], docStyles['sectionHeader'], docStyles['docsHeader'])}>
77+
{children}
78+
<span className={docStyles['headingAnchor']}>
79+
<a className={clsx(linkStyle['spectrum-Link'], docStyles.link, docStyles.anchor)} href={`#${props.id}`} aria-label={`Direct link to ${children}`}>#</a>
80+
</span>
81+
</h4>
82+
),
7583
p: ({children, ...props}) => <p className={typographyStyles['spectrum-Body3']} {...props}>{children}</p>,
7684
ul: ({children, ...props}) => <ul {...props} className={typographyStyles['spectrum-Body3']}>{children}</ul>,
7785
ol: ({children, ...props}) => <ol {...props} className={typographyStyles['spectrum-Body3']}>{children}</ol>,

packages/dev/docs/src/StateTable.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ import styles from './docs.css';
1717
import tableStyles from '@adobe/spectrum-css-temp/components/table/vars.css';
1818
import typographyStyles from '@adobe/spectrum-css-temp/components/typography/vars.css';
1919

20-
export function StateTable({properties}) {
20+
export function StateTable({properties, showOptional}) {
21+
let props = Object.values(properties);
22+
if (!showOptional) {
23+
props = props.filter(prop => !prop.optional);
24+
}
25+
2126
return (
2227
<table className={`${tableStyles['spectrum-Table']} ${tableStyles['spectrum-Table--quiet']} ${styles.propTable}`}>
2328
<thead>
@@ -28,7 +33,7 @@ export function StateTable({properties}) {
2833
</tr>
2934
</thead>
3035
<tbody className={tableStyles['spectrum-Table-body']}>
31-
{Object.values(properties).map((prop, index) => (
36+
{props.map((prop, index) => (
3237
<tr key={index} className={clsx(tableStyles['spectrum-Table-row'], styles.tableRow)}>
3338
<td role="rowheader" className={clsx(tableStyles['spectrum-Table-cell'], styles.tableCell)} data-column="Name">
3439
<code className={`${typographyStyles['spectrum-Code4']}`}>

packages/dev/parcel-transformer-mdx-docs/MDXTransformer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ module.exports = new Transformer({
8787

8888
// We'd like to exclude certain sections of the code from being rendered on the page, but they need to be there to actually
8989
// execute. So, you can wrap that section in a ///- begin collapse -/// ... ///- end collapse -/// block to mark it.
90-
node.value = node.value.replace(/\n*\/\/\/- begin collapse -\/\/\/(.|\n)*?\/\/\/- end collapse -\/\/\//g, () => '').trim();
90+
node.value = node.value.replace(/\n*\/\/\/- begin collapse -\/\/\/(.|\n)*?\/\/\/- end collapse -\/\/\/(\s*\n*(?=\s*(\/\/|\/\*)))?/g, () => '').trim();
9191

9292
if (options.includes('render=false')) {
9393
node.meta = null;

packages/react-aria-components/docs/ComboBox.mdx

+16-10
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,13 @@ import {ComboBox, Label, Input, Button, Popover, ListBox, Item} from 'react-aria
118118
.react-aria-ListBox {
119119
--highlight-background: slateblue;
120120
--highlight-foreground: white;
121-
--border-color: var(--spectrum-global-color-gray-400);
122-
--background-color: var(--page-background);
123121
--text-color: var(--spectrum-alias-text-color);
124122
--text-color-disabled: var(--spectrum-alias-text-color-disabled);
125123

126124
max-height: inherit;
127125
overflow: auto;
128126
padding: 2px;
129-
border: 1px solid var(--border-color);
130-
box-shadow: 0 8px 20px rgba(0 0 0 / 0.1);
131-
border-radius: 6px;
132-
background: var(--background-color);
133-
width: var(--combobox-width);
134-
box-sizing: border-box;
127+
outline: none;
135128

136129
.react-aria-Section:not(:first-child) {
137130
margin-top: 12px;
@@ -188,6 +181,19 @@ import {ComboBox, Label, Input, Button, Popover, ListBox, Item} from 'react-aria
188181
}
189182
}
190183

184+
.react-aria-Popover {
185+
--background-color: var(--page-background);
186+
--border-color: var(--spectrum-global-color-gray-400);
187+
188+
border: 1px solid var(--border-color);
189+
width: var(--trigger-width);
190+
box-sizing: border-box;
191+
box-shadow: 0 8px 20px rgba(0 0 0 / 0.1);
192+
border-radius: 6px;
193+
background: var(--background-color);
194+
outline: none;
195+
}
196+
191197
@media (forced-colors: active) {
192198
.react-aria-ListBox {
193199
forced-color-adjust: none;
@@ -425,11 +431,11 @@ A [Button](Button.html) can be targeted with the `.react-aria-Button` CSS select
425431

426432
The [Popover](Popover.html) component can be targeted with the `.react-aria-Popover` CSS selector, or by overriding with a custom `className`. Note that it renders in a [React Portal](https://reactjs.org/docs/portals.html), so it will not appear as a descendant of the ComboBox in the DOM.
427433

428-
The `--combobox-width` CSS custom property will be set on the popover, which you can use to make the popover match the width of the combobox.
434+
The `--trigger-width` CSS custom property will be set on the popover, which you can use to make the popover match the width of the combobox.
429435

430436
```css render=false
431437
.react-aria-Popover {
432-
width: var(--combobox-width);
438+
width: var(--trigger-width);
433439
}
434440
```
435441

packages/react-aria-components/docs/Dialog.mdx

+15-5
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ A `Dialog` may be placed within a [Popover](Popover.html) to display it in conte
273273
import {Popover, OverlayArrow} from 'react-aria-components';
274274

275275
<DialogTrigger>
276-
<Button aria-label="Help">?⃝</Button>
276+
<Button aria-label="Help"></Button>
277277
<Popover>
278278
<OverlayArrow>
279279
<svg width={12} height={12}><path d="M0 0,L6 6,L12 0" /></svg>
@@ -291,18 +291,21 @@ import {Popover, OverlayArrow} from 'react-aria-components';
291291

292292
```css
293293
.react-aria-Popover {
294-
border: 1px solid var(--spectrum-global-color-gray-400);
294+
--background-color: var(--page-background);
295+
--border-color: var(--spectrum-global-color-gray-400);
296+
297+
border: 1px solid var(--border-color);
295298
box-shadow: 0 8px 20px rgba(0 0 0 / 0.1);
296299
border-radius: 6px;
297-
background: var(--page-background);
300+
background: var(--background-color);
298301
outline: none;
299302
padding: 30px;
300303
max-width: 250px;
301304

302305
& .react-aria-OverlayArrow svg {
303306
display: block;
304-
fill: var(--page-background);
305-
stroke: var(--spectrum-global-color-gray-400);
307+
fill: var(--background-color);
308+
stroke: var(--border-color);
306309
stroke-width: 1px;
307310
}
308311

@@ -355,6 +358,13 @@ import {Popover, OverlayArrow} from 'react-aria-components';
355358
opacity: 1;
356359
}
357360
}
361+
362+
@media (forced-colors: active) {
363+
.react-aria-Popover {
364+
--background-color: Canvas;
365+
--border-color: ButtonBorder;
366+
}
367+
}
358368
```
359369

360370
</details>

0 commit comments

Comments
 (0)