diff --git a/.storybook-s2/docs/Migrating.jsx b/.storybook-s2/docs/Migrating.jsx index 96fdecb712b..f819f96d16e 100644 --- a/.storybook-s2/docs/Migrating.jsx +++ b/.storybook-s2/docs/Migrating.jsx @@ -114,6 +114,9 @@ export function Migrating() {

ButtonGroup

No updates needed.

+

Calendar

+

No updates needed.

+

Checkbox

No updates needed.

@@ -158,6 +161,27 @@ export function Migrating() {
  • Update Item to be a ComboBoxItem
  • +

    DateField

    + + +

    DatePicker

    + + +

    DateRangePicker

    + +

    Dialog

    +

    RangeCalendar

    +

    No updates needed.

    +

    RangeSlider

    +

    TimeField

    + +

    ToggleButton

    No updates needed.

    diff --git a/packages/@react-aria/dnd/src/DragManager.ts b/packages/@react-aria/dnd/src/DragManager.ts index 9e0773ed230..2128797ffb4 100644 --- a/packages/@react-aria/dnd/src/DragManager.ts +++ b/packages/@react-aria/dnd/src/DragManager.ts @@ -410,7 +410,7 @@ class DragSession { ...visibleDropTargets.flatMap(target => target.activateButtonRef?.current ? [target.element, target.activateButtonRef?.current] : [target.element]) ], {shouldUseInert: true}); - this.mutationObserver.observe(document.body, {subtree: true, attributes: true, attributeFilter: ['aria-hidden']}); + this.mutationObserver.observe(document.body, {subtree: true, attributes: true, attributeFilter: ['aria-hidden', 'inert']}); } next(): void { @@ -437,7 +437,7 @@ class DragSession { // If we've reached the end of the valid drop targets, cycle back to the original drag target. // This lets the user cancel the drag in case they don't have an Escape key (e.g. iPad keyboard case). if (index === this.validDropTargets.length - 1) { - if (!this.dragTarget.element.closest('[aria-hidden="true"]')) { + if (!this.dragTarget.element.closest('[aria-hidden="true"], [inert]')) { this.setCurrentDropTarget(null); this.dragTarget.element.focus(); } else { @@ -472,7 +472,7 @@ class DragSession { // If we've reached the start of the valid drop targets, cycle back to the original drag target. // This lets the user cancel the drag in case they don't have an Escape key (e.g. iPad keyboard case). if (index === 0) { - if (!this.dragTarget.element.closest('[aria-hidden="true"]')) { + if (!this.dragTarget.element.closest('[aria-hidden="true"], [inert]')) { this.setCurrentDropTarget(null); this.dragTarget.element.focus(); } else { @@ -579,7 +579,7 @@ class DragSession { cancel(): void { this.setCurrentDropTarget(null); this.end(); - if (!this.dragTarget.element.closest('[aria-hidden="true"]')) { + if (!this.dragTarget.element.closest('[aria-hidden="true"], [inert]')) { this.dragTarget.element.focus(); } @@ -640,7 +640,7 @@ class DragSession { function findValidDropTargets(options: DragTarget) { let types = getTypes(options.items); return [...dropTargets.values()].filter(target => { - if (target.element.closest('[aria-hidden="true"]')) { + if (target.element.closest('[aria-hidden="true"], [inert]')) { return false; } diff --git a/packages/@react-spectrum/s2/src/DateRangePicker.tsx b/packages/@react-spectrum/s2/src/DateRangePicker.tsx index b2113effdc8..6132469899a 100644 --- a/packages/@react-spectrum/s2/src/DateRangePicker.tsx +++ b/packages/@react-spectrum/s2/src/DateRangePicker.tsx @@ -150,7 +150,7 @@ export const DateRangePicker = /*#__PURE__*/ (forwardRef as forwardRefType)(func isDateUnavailable={isDateUnavailable} pageBehavior={pageBehavior} /> {showTimeField && ( -
    +
    - + + + + + +
    " `; + +exports[`changes validationState to isInvalid or nothing 1`] = ` +"import { DateField } from "@react-spectrum/s2"; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    " +`; diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/datepicker.test.ts.snap b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/datepicker.test.ts.snap index 5d59549159a..48e9c869956 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/datepicker.test.ts.snap +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/datepicker.test.ts.snap @@ -1,9 +1,30 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Does nothing 1`] = ` +exports[`Removes isQuiet 1`] = ` "import { DatePicker } from "@react-spectrum/s2"; - +let isQuiet = true; +let props = {isQuiet: true};
    - + + + + + +
    " `; + +exports[`changes validationState to isInvalid or nothing 1`] = ` +"import { DatePicker } from "@react-spectrum/s2"; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    " +`; diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/daterangepicker.test.ts.snap b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/daterangepicker.test.ts.snap index 7162dc296c1..eac94a75277 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/daterangepicker.test.ts.snap +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/daterangepicker.test.ts.snap @@ -1,9 +1,30 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Does nothing 1`] = ` +exports[`Removes isQuiet 1`] = ` "import { DateRangePicker } from "@react-spectrum/s2"; - +let isQuiet = true; +let props = {isQuiet: true};
    - + + + + + +
    " `; + +exports[`changes validationState to isInvalid or nothing 1`] = ` +"import { DateRangePicker } from "@react-spectrum/s2"; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    " +`; diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/timefield.test.ts.snap b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/timefield.test.ts.snap index 4a845dc25b8..66d69951a4b 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/timefield.test.ts.snap +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/timefield.test.ts.snap @@ -1,8 +1,30 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Renames variants 1`] = ` -"// import {Button} from '@adobe/react-spectrum'; - +exports[`Removes isQuiet 1`] = ` +"import { TimeField } from "@react-spectrum/s2"; +let isQuiet = true; +let props = {isQuiet: true};
    + + + + + +
    " `; + +exports[`changes validationState to isInvalid or nothing 1`] = ` +"import { TimeField } from "@react-spectrum/s2"; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    " +`; diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/datefield.test.ts b/packages/dev/codemods/src/s1-to-s2/__tests__/datefield.test.ts index 48ff6f6254e..85bdd1554b6 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/datefield.test.ts +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/datefield.test.ts @@ -6,10 +6,30 @@ const test = (name: string, input: string) => { defineSnapshotTest(transform, {}, input, name); }; -test('Does nothing', ` -import {DateField} from '@adobe/react-spectrum'; +test('Removes isQuiet', ` +import {DateField} from '@adobe/react-spectrum'; +let isQuiet = true; +let props = {isQuiet: true};
    - + + + + + +
    `); + + +test('changes validationState to isInvalid or nothing', ` + import {DateField} from '@adobe/react-spectrum'; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    +`); diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/datepicker.test.ts b/packages/dev/codemods/src/s1-to-s2/__tests__/datepicker.test.ts index f6e8c413206..cd8191a9b94 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/datepicker.test.ts +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/datepicker.test.ts @@ -6,10 +6,30 @@ const test = (name: string, input: string) => { defineSnapshotTest(transform, {}, input, name); }; -test('Does nothing', ` -import {DatePicker} from '@adobe/react-spectrum'; +test('Removes isQuiet', ` +import {DatePicker} from '@adobe/react-spectrum'; +let isQuiet = true; +let props = {isQuiet: true};
    - + + + + + +
    `); + + +test('changes validationState to isInvalid or nothing', ` + import {DatePicker} from '@adobe/react-spectrum'; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    +`); diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/daterangepicker.test.ts b/packages/dev/codemods/src/s1-to-s2/__tests__/daterangepicker.test.ts index 8c8191602f0..33da5d45c6c 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/daterangepicker.test.ts +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/daterangepicker.test.ts @@ -6,10 +6,30 @@ const test = (name: string, input: string) => { defineSnapshotTest(transform, {}, input, name); }; -test('Does nothing', ` -import {DateRangePicker} from '@adobe/react-spectrum'; +test('Removes isQuiet', ` +import {DateRangePicker} from '@adobe/react-spectrum'; +let isQuiet = true; +let props = {isQuiet: true};
    - + + + + + +
    `); + + +test('changes validationState to isInvalid or nothing', ` + import {DateRangePicker} from '@adobe/react-spectrum'; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    +`); diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/timefield.test.ts b/packages/dev/codemods/src/s1-to-s2/__tests__/timefield.test.ts index a7b16598b27..f14b1b3d450 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/timefield.test.ts +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/timefield.test.ts @@ -6,9 +6,30 @@ const test = (name: string, input: string) => { defineSnapshotTest(transform, {}, input, name); }; -test('Renames variants', ` -// import {Button} from '@adobe/react-spectrum'; +test('Removes isQuiet', ` +import {TimeField} from '@adobe/react-spectrum'; +let isQuiet = true; +let props = {isQuiet: true};
    + + + + + +
    `); + + +test('changes validationState to isInvalid or nothing', ` + import {TimeField} from '@adobe/react-spectrum'; + let validationState = 'invalid'; + let props = {validationState: 'invalid'}; +
    + + + + +
    +`); diff --git a/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DateField/transform.ts b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DateField/transform.ts new file mode 100644 index 00000000000..0cf1f9173b0 --- /dev/null +++ b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DateField/transform.ts @@ -0,0 +1,28 @@ +import {NodePath} from '@babel/traverse'; +import { + removeProp, + updatePropNameAndValue +} from '../../shared/transforms'; +import * as t from '@babel/types'; + +/** + * Transforms DateField: + * - Remove isQuiet (it is no longer supported in Spectrum 2). + * - Change validationState="invalid" to isInvalid. + * - Remove validationState="valid" (it is no longer supported in Spectrum 2). + */ +export default function transformDateField(path: NodePath): void { + // Change validationState="invalid" to isInvalid + updatePropNameAndValue(path, { + oldPropName: 'validationState', + oldPropValue: 'invalid', + newPropName: 'isInvalid', + newPropValue: true + }); + + // Remove validationState="valid" + removeProp(path, {propName: 'validationState', propValue: 'valid'}); + + // Remove isQuiet + removeProp(path, {propName: 'isQuiet'}); +} diff --git a/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DatePicker/transform.ts b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DatePicker/transform.ts new file mode 100644 index 00000000000..566d918ee96 --- /dev/null +++ b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DatePicker/transform.ts @@ -0,0 +1,28 @@ +import {NodePath} from '@babel/traverse'; +import { + removeProp, + updatePropNameAndValue +} from '../../shared/transforms'; +import * as t from '@babel/types'; + +/** + * Transforms DatePicker: + * - Remove isQuiet (it is no longer supported in Spectrum 2). + * - Change validationState="invalid" to isInvalid. + * - Remove validationState="valid" (it is no longer supported in Spectrum 2). + */ +export default function transformDatePicker(path: NodePath): void { + // Change validationState="invalid" to isInvalid + updatePropNameAndValue(path, { + oldPropName: 'validationState', + oldPropValue: 'invalid', + newPropName: 'isInvalid', + newPropValue: true + }); + + // Remove validationState="valid" + removeProp(path, {propName: 'validationState', propValue: 'valid'}); + + // Remove isQuiet + removeProp(path, {propName: 'isQuiet'}); +} diff --git a/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DateRangePicker/transform.ts b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DateRangePicker/transform.ts new file mode 100644 index 00000000000..725815a0c88 --- /dev/null +++ b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/DateRangePicker/transform.ts @@ -0,0 +1,28 @@ +import {NodePath} from '@babel/traverse'; +import { + removeProp, + updatePropNameAndValue +} from '../../shared/transforms'; +import * as t from '@babel/types'; + +/** + * Transforms DateRangePicker: + * - Remove isQuiet (it is no longer supported in Spectrum 2). + * - Change validationState="invalid" to isInvalid. + * - Remove validationState="valid" (it is no longer supported in Spectrum 2). + */ +export default function transformDateRangePicker(path: NodePath): void { + // Change validationState="invalid" to isInvalid + updatePropNameAndValue(path, { + oldPropName: 'validationState', + oldPropValue: 'invalid', + newPropName: 'isInvalid', + newPropValue: true + }); + + // Remove validationState="valid" + removeProp(path, {propName: 'validationState', propValue: 'valid'}); + + // Remove isQuiet + removeProp(path, {propName: 'isQuiet'}); +} diff --git a/packages/dev/codemods/src/s1-to-s2/src/codemods/components/TimeField/transform.ts b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/TimeField/transform.ts new file mode 100644 index 00000000000..8e2bed6f1f2 --- /dev/null +++ b/packages/dev/codemods/src/s1-to-s2/src/codemods/components/TimeField/transform.ts @@ -0,0 +1,28 @@ +import {NodePath} from '@babel/traverse'; +import { + removeProp, + updatePropNameAndValue +} from '../../shared/transforms'; +import * as t from '@babel/types'; + +/** + * Transforms TimeField: + * - Remove isQuiet (it is no longer supported in Spectrum 2). + * - Change validationState="invalid" to isInvalid. + * - Remove validationState="valid" (it is no longer supported in Spectrum 2). + */ +export default function transformTimeField(path: NodePath): void { + // Change validationState="invalid" to isInvalid + updatePropNameAndValue(path, { + oldPropName: 'validationState', + oldPropValue: 'invalid', + newPropName: 'isInvalid', + newPropValue: true + }); + + // Remove validationState="valid" + removeProp(path, {propName: 'validationState', propValue: 'valid'}); + + // Remove isQuiet + removeProp(path, {propName: 'isQuiet'}); +} diff --git a/packages/react-aria-components/src/TreeDropTargetDelegate.ts b/packages/react-aria-components/src/TreeDropTargetDelegate.ts index daee51861ed..ba3d952d1e9 100644 --- a/packages/react-aria-components/src/TreeDropTargetDelegate.ts +++ b/packages/react-aria-components/src/TreeDropTargetDelegate.ts @@ -84,11 +84,15 @@ export class TreeDropTargetDelegate { if (target.dropPosition === 'before') { let keyBefore = this.state!.collection.getKeyBefore(target.key); if (keyBefore != null) { - target = { + let convertedTarget = { type: 'item', key: keyBefore, dropPosition: 'after' } as const; + + if (isValidDropTarget(convertedTarget)) { + target = convertedTarget; + } } }