From f2d996d3c298c953ae743517e021c272898249fb Mon Sep 17 00:00:00 2001 From: mehm8128 <83744975+mehm8128@users.noreply.github.com> Date: Wed, 20 Nov 2024 01:40:18 +0900 Subject: [PATCH 1/5] docs: add APG grid link to useTagGroup doc (#7367) * add APG grid link to useTagGroup doc * add grid keywords to TagGroup --- packages/@react-aria/tag/docs/useTagGroup.mdx | 7 +++++-- packages/react-aria-components/docs/TagGroup.mdx | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/@react-aria/tag/docs/useTagGroup.mdx b/packages/@react-aria/tag/docs/useTagGroup.mdx index 6643948021a..38701fd308c 100644 --- a/packages/@react-aria/tag/docs/useTagGroup.mdx +++ b/packages/@react-aria/tag/docs/useTagGroup.mdx @@ -23,7 +23,7 @@ import Anatomy from './anatomy.svg'; --- category: Collections -keywords: [tag, aria] +keywords: [tag, aria, grid] --- # useTagGroup @@ -32,7 +32,10 @@ keywords: [tag, aria] + componentNames={['useTagGroup']} + sourceData={[ + {type: 'W3C', url: 'https://www.w3.org/WAI/ARIA/apg/patterns/grid/'} + ]} /> ## API diff --git a/packages/react-aria-components/docs/TagGroup.mdx b/packages/react-aria-components/docs/TagGroup.mdx index 54ae7775aa8..0868156df51 100644 --- a/packages/react-aria-components/docs/TagGroup.mdx +++ b/packages/react-aria-components/docs/TagGroup.mdx @@ -26,7 +26,7 @@ import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; --- category: Collections -keywords: [tag, aria] +keywords: [tag, aria, grid] type: component --- From f33288c867e305341b63b4ec88e55bc566ae115e Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Tue, 19 Nov 2024 10:02:57 -0800 Subject: [PATCH 2/5] fix: Revert displaying popovers as modals on mobile for now (#7392) * Revert displaying popovers as modals on mobile for now * Improve story example * Add padding between fullscreen dialog content and buttons on small screens * Remove mobileType for now --- .../s2/src/FullscreenDialog.tsx | 2 + packages/@react-spectrum/s2/src/Popover.tsx | 53 +++++++++---------- .../s2/stories/Popover.stories.tsx | 8 ++- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/packages/@react-spectrum/s2/src/FullscreenDialog.tsx b/packages/@react-spectrum/s2/src/FullscreenDialog.tsx index df13e330bc4..cebdd87d99d 100644 --- a/packages/@react-spectrum/s2/src/FullscreenDialog.tsx +++ b/packages/@react-spectrum/s2/src/FullscreenDialog.tsx @@ -72,6 +72,7 @@ export const dialogInner = style({ 'header', '.', 'content', + '.', 'buttons' ], sm: [ @@ -90,6 +91,7 @@ export const dialogInner = style({ 'auto', 24, '1fr', + 24, 'auto' ], sm: [ diff --git a/packages/@react-spectrum/s2/src/Popover.tsx b/packages/@react-spectrum/s2/src/Popover.tsx index ce8b55f399f..badb86587a3 100644 --- a/packages/@react-spectrum/s2/src/Popover.tsx +++ b/packages/@react-spectrum/s2/src/Popover.tsx @@ -16,22 +16,19 @@ import { composeRenderProps, Dialog, DialogProps, - ModalRenderProps, OverlayArrow, OverlayTriggerStateContext, useLocale } from 'react-aria-components'; import {colorScheme, getAllowedOverrides, StyleProps, UnsafeStyles} from './style-utils' with {type: 'macro'}; import {ColorSchemeContext} from './Provider'; -import {DismissButton} from 'react-aria'; import {DOMRef} from '@react-types/shared'; import {forwardRef, MutableRefObject, useCallback, useContext} from 'react'; import {keyframes} from '../style/style-macro' with {type: 'macro'}; import {mergeStyles} from '../style/runtime'; -import {Modal} from './Modal'; import {style} from '../style' with {type: 'macro'}; import {StyleString} from '../style/types' with {type: 'macro'}; -import {useDOMRef, useIsMobileDevice} from '@react-spectrum/utils'; +import {useDOMRef} from '@react-spectrum/utils'; export interface PopoverProps extends UnsafeStyles, Omit { styles?: StyleString, @@ -44,9 +41,9 @@ export interface PopoverProps extends UnsafeStyles, Omit) { UNSAFE_className = '', UNSAFE_style, styles, - size, - children, - trigger = null + size } = props; let domRef = useDOMRef(ref); let colorScheme = useContext(ColorSchemeContext); @@ -239,24 +237,25 @@ function PopoverBase(props: PopoverProps, ref: DOMRef) { }, [locale, direction, domRef]); // On small devices, show a modal (or eventually a tray) instead of a popover. - let isMobile = useIsMobileDevice(); - if (isMobile && process.env.NODE_ENV !== 'test') { - let mappedChildren = typeof children === 'function' - ? (renderProps: ModalRenderProps) => children({...renderProps, defaultChildren: null, trigger, placement: 'bottom'}) - : children; + // TODO: reverted this until we have trays. + // let isMobile = useIsMobileDevice(); + // if (isMobile && process.env.NODE_ENV !== 'test') { + // let mappedChildren = typeof children === 'function' + // ? (renderProps: ModalRenderProps) => children({...renderProps, defaultChildren: null, trigger, placement: 'bottom'}) + // : children; - return ( - - {composeRenderProps(mappedChildren, (children, {state}) => ( - <> - {children} - {/* Add additional dismiss button at the end to match popovers. */} - - - ))} - - ); - } + // return ( + // + // {composeRenderProps(mappedChildren, (children, {state}) => ( + // <> + // {children} + // {/* Add additional dismiss button at the end to match popovers. */} + // + // + // ))} + // + // ); + // } // TODO: this still isn't the final popover 'tip', copying various ones out of the designs files yields different results // containerPadding not working as expected @@ -289,7 +288,7 @@ function PopoverBase(props: PopoverProps, ref: DOMRef) { let _PopoverBase = forwardRef(PopoverBase); export {_PopoverBase as PopoverBase}; -export interface PopoverDialogProps extends Pick, Omit, StyleProps {} +export interface PopoverDialogProps extends Pick, Omit, StyleProps {} const dialogStyle = style({ padding: 8, diff --git a/packages/@react-spectrum/s2/stories/Popover.stories.tsx b/packages/@react-spectrum/s2/stories/Popover.stories.tsx index 7b195e0e6dd..a4fcbaeee32 100644 --- a/packages/@react-spectrum/s2/stories/Popover.stories.tsx +++ b/packages/@react-spectrum/s2/stories/Popover.stories.tsx @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import {ActionButton, Avatar, Button, Card, CardPreview, Content, DialogTrigger, Divider, DropZone, Form, Image, Menu, MenuItem, MenuSection, Popover, SearchField, SubmenuTrigger, Switch, Tab, TabList, TabPanel, Tabs, Text, TextField} from '../src'; +import {ActionButton, Avatar, Button, Card, CardPreview, Content, DialogTrigger, Divider, Form, Image, Menu, MenuItem, MenuSection, Popover, SearchField, SubmenuTrigger, Switch, Tab, TabList, TabPanel, Tabs, Text, TextField} from '../src'; import Cloud from '../s2wf-icons/S2_Icon_Cloud_20_N.svg'; import Education from '../s2wf-icons/S2_Icon_Education_20_N.svg'; import File from '../s2wf-icons/S2_Icon_File_20_N.svg'; @@ -97,7 +97,6 @@ export const HelpCenter = (args: any) => (
- Adobe can contact me for further questions concerning this feedback @@ -159,3 +158,8 @@ export const AccountMenu = (args: any) => ( ); + +AccountMenu.argTypes = { + hideArrow: {table: {disable: true}}, + placement: {table: {disable: true}} +}; From 52e167d254fa449cd5c8c26fba00ed868be1a100 Mon Sep 17 00:00:00 2001 From: Robert Snow Date: Wed, 20 Nov 2024 09:14:41 +1100 Subject: [PATCH 3/5] chore: Revert exactOptionalPropertyTypes id support (#7400) --- packages/@react-types/shared/src/dom.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@react-types/shared/src/dom.d.ts b/packages/@react-types/shared/src/dom.d.ts index d0d3fe03e5e..88fea2c1c13 100644 --- a/packages/@react-types/shared/src/dom.d.ts +++ b/packages/@react-types/shared/src/dom.d.ts @@ -59,7 +59,7 @@ export interface DOMProps { /** * The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id). */ - id?: string | undefined + id?: string } export interface FocusableDOMProps extends DOMProps { From 8217bd47d75fa02ffa49e13aa27ebc62dc6ab1ef Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Tue, 19 Nov 2024 16:31:38 -0800 Subject: [PATCH 4/5] chore: Update S2 Dialog codemods (#7388) * Rename isDismissable to isDismissible * Update Dialog codemod * Fix TS strict --- .../@react-spectrum/s2/src/CustomDialog.tsx | 8 +- packages/@react-spectrum/s2/src/Dialog.tsx | 16 +-- .../s2/src/DialogContainer.tsx | 8 +- .../s2/stories/CustomDialog.stories.tsx | 2 +- .../__snapshots__/dialog.test.ts.snap | 111 ++++++++++++++++++ .../src/s1-to-s2/__tests__/dialog.test.ts | 101 ++++++++++++++++ .../src/s1-to-s2/src/codemods/changes.ts | 28 +++++ .../src/s1-to-s2/src/codemods/transforms.ts | 59 +++++++++- 8 files changed, 314 insertions(+), 19 deletions(-) diff --git a/packages/@react-spectrum/s2/src/CustomDialog.tsx b/packages/@react-spectrum/s2/src/CustomDialog.tsx index 4d7f33cdde9..ffb12576af5 100644 --- a/packages/@react-spectrum/s2/src/CustomDialog.tsx +++ b/packages/@react-spectrum/s2/src/CustomDialog.tsx @@ -24,9 +24,9 @@ export interface CustomDialogProps extends Omit + , StyleProps { /** - * Whether the Dialog is dismissable. + * Whether the Dialog is dismissible. */ - isDismissable?: boolean, + isDismissible?: boolean, /** * The size of the Dialog. * @@ -91,11 +91,11 @@ export const dialogInner = style({ }); function Dialog(props: DialogProps, ref: DOMRef) { - let {size = 'M', isDismissable, isKeyboardDismissDisabled} = props; + let {size = 'M', isDismissible, isKeyboardDismissDisabled} = props; let domRef = useDOMRef(ref); return ( - + + })({isDismissible: props.isDismissible})}>
- {props.isDismissable && + {props.isDismissible && } @@ -214,7 +214,7 @@ function Dialog(props: DialogProps, ref: DOMRef) { [HeaderContext, {isHidden: true}], [ContentContext, {isHidden: true}], [FooterContext, {styles: footer}], - [ButtonGroupContext, {isHidden: props.isDismissable, styles: buttonGroup, align: 'end'}] + [ButtonGroupContext, {isHidden: props.isDismissible, styles: buttonGroup, align: 'end'}] ]}> {children} diff --git a/packages/@react-spectrum/s2/src/DialogContainer.tsx b/packages/@react-spectrum/s2/src/DialogContainer.tsx index dd7268b29f4..ab9debb936c 100644 --- a/packages/@react-spectrum/s2/src/DialogContainer.tsx +++ b/packages/@react-spectrum/s2/src/DialogContainer.tsx @@ -14,7 +14,7 @@ import {ModalContext, useSlottedContext} from 'react-aria-components'; import React, {ReactElement, useState} from 'react'; import {SpectrumDialogContainerProps} from '@react-types/dialog'; -export interface DialogContainerProps extends Omit {} +export interface DialogContainerProps extends Omit {} /** * A DialogContainer accepts a single Dialog as a child, and manages showing and hiding @@ -24,9 +24,7 @@ export interface DialogContainerProps extends Omit + {lastChild} ); diff --git a/packages/@react-spectrum/s2/stories/CustomDialog.stories.tsx b/packages/@react-spectrum/s2/stories/CustomDialog.stories.tsx index c5ac7bba181..8571fc544fa 100644 --- a/packages/@react-spectrum/s2/stories/CustomDialog.stories.tsx +++ b/packages/@react-spectrum/s2/stories/CustomDialog.stories.tsx @@ -33,7 +33,7 @@ export default meta; export const WhatsNew = (args: any) => ( Open dialog - +
What's new diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/dialog.test.ts.snap b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/dialog.test.ts.snap index 5254db8dd8d..fcc1a32b352 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/dialog.test.ts.snap +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/__snapshots__/dialog.test.ts.snap @@ -62,6 +62,36 @@ exports[`Moves close function from DialogTrigger to Dialog 1`] = ` " `; +exports[`Moves isDismissable 1`] = ` +"import { DialogTrigger, Button, Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; + + + + + Test + + Content + +" +`; + +exports[`Moves isDismissable from DialogContainer 1`] = ` +"import { DialogContainer, Button, Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; + + + {showDialog1 && + Test + + Content + } + {showDialog2 && + Test + + Content + } +" +`; + exports[`Removes divider 1`] = ` "import { Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; @@ -90,6 +120,87 @@ exports[`Removes onDismiss and leaves a comment 1`] = ` " `; +exports[`Replaces type="fullscreen" with FullscreenDialog component 1`] = ` +"import { FullscreenDialog, DialogTrigger, Button, Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; + + + + + Test + + Content + +" +`; + +exports[`Replaces type="fullscreen" with FullscreenDialog component in DialogContainer 1`] = ` +"import { + FullscreenDialog, + DialogContainer, + Button, + Dialog, + Heading, + Content, + Divider, +} from "@react-spectrum/s2"; + + + {showDialog1 && + Test + + Content + } + {showDialog2 && + Test + + Content + } +" +`; + +exports[`Replaces type="fullscreenTakeover" with FullscreenDialog component 1`] = ` +"import { FullscreenDialog, DialogTrigger, Button, Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; + + + + + Test + + Content + +" +`; + +exports[`Replaces type="fullscreenTakeover" with FullscreenDialog component and close function 1`] = ` +"import { FullscreenDialog, DialogTrigger, Button, Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; + + + + {( + { + close + } + ) => <> + Test + + Content + } +" +`; + +exports[`Replaces type="popover" with Popover component 1`] = ` +"import { Popover, DialogTrigger, Button, Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; + + + + + Test + + Content + +" +`; + exports[`bails when it cannot move the close function 1`] = ` "import { DialogTrigger, Button, Dialog, Heading, Content, Divider } from "@react-spectrum/s2"; diff --git a/packages/dev/codemods/src/s1-to-s2/__tests__/dialog.test.ts b/packages/dev/codemods/src/s1-to-s2/__tests__/dialog.test.ts index 24567cff444..d6226cbf27c 100644 --- a/packages/dev/codemods/src/s1-to-s2/__tests__/dialog.test.ts +++ b/packages/dev/codemods/src/s1-to-s2/__tests__/dialog.test.ts @@ -110,3 +110,104 @@ import {DialogTrigger, Button, Dialog, Heading, Content, Divider} from '@adobe/r } `); + +test('Moves isDismissable', ` +import {DialogTrigger, Button, Dialog, Heading, Content, Divider} from '@adobe/react-spectrum'; + + + + + Test + + Content + + +`); + +test('Replaces type="popover" with Popover component', ` +import {DialogTrigger, Button, Dialog, Heading, Content, Divider} from '@adobe/react-spectrum'; + + + + + Test + + Content + + +`); + +test('Replaces type="fullscreen" with FullscreenDialog component', ` +import {DialogTrigger, Button, Dialog, Heading, Content, Divider} from '@adobe/react-spectrum'; + + + + + Test + + Content + + +`); + +test('Replaces type="fullscreenTakeover" with FullscreenDialog component', ` +import {DialogTrigger, Button, Dialog, Heading, Content, Divider} from '@adobe/react-spectrum'; + + + + + Test + + Content + + +`); + +test('Replaces type="fullscreenTakeover" with FullscreenDialog component and close function', ` +import {DialogTrigger, Button, Dialog, Heading, Content, Divider} from '@adobe/react-spectrum'; + + + + {(close) => + + Test + + Content + + } + +`); + +test('Moves isDismissable from DialogContainer', ` +import {DialogContainer, Button, Dialog, Heading, Content, Divider} from '@adobe/react-spectrum'; + + + {showDialog1 && + Test + + Content + } + {showDialog2 && + Test + + Content + } + +`); + +test('Replaces type="fullscreen" with FullscreenDialog component in DialogContainer', ` +import {DialogContainer, Button, Dialog, Heading, Content, Divider} from '@adobe/react-spectrum'; + + + {showDialog1 && + Test + + Content + } + {showDialog2 && + Test + + Content + } + +`); diff --git a/packages/dev/codemods/src/s1-to-s2/src/codemods/changes.ts b/packages/dev/codemods/src/s1-to-s2/src/codemods/changes.ts index c1e74517171..2eeb5d2e5cd 100644 --- a/packages/dev/codemods/src/s1-to-s2/src/codemods/changes.ts +++ b/packages/dev/codemods/src/s1-to-s2/src/codemods/changes.ts @@ -75,6 +75,10 @@ type FunctionInfo = | { name: 'updateLegacyLink', args: {} + } + | { + name: 'updateDialogChild', + args: {} }; type Change = { @@ -428,6 +432,30 @@ export const changes: ChangesJSON = { name: 'moveRenderPropsToChild', args: {newChildComponent: 'Dialog'} } + }, + { + description: 'Rename isDismissable to isDismissible', + reason: 'Fixed spelling', + function: {name: 'updatePropName', args: {oldProp: 'isDismissable', newProp: 'isDismissible'}} + }, + { + description: 'Update Dialog child to Popover or FullscreenDialog depending on type prop', + reason: 'Updated API', + function: {name: 'updateDialogChild', args: {}} + } + ] + }, + DialogContainer: { + changes: [ + { + description: 'Rename isDismissable to isDismissible', + reason: 'Fixed spelling', + function: {name: 'updatePropName', args: {oldProp: 'isDismissable', newProp: 'isDismissible'}} + }, + { + description: 'Update Dialog child to Popover or FullscreenDialog depending on type prop', + reason: 'Updated API', + function: {name: 'updateDialogChild', args: {}} } ] }, diff --git a/packages/dev/codemods/src/s1-to-s2/src/codemods/transforms.ts b/packages/dev/codemods/src/s1-to-s2/src/codemods/transforms.ts index d643b81394f..370e792784d 100644 --- a/packages/dev/codemods/src/s1-to-s2/src/codemods/transforms.ts +++ b/packages/dev/codemods/src/s1-to-s2/src/codemods/transforms.ts @@ -960,6 +960,62 @@ function updateLegacyLink( } } +/** + * Updates DialogTrigger and DialogContainer to the new API. + * + * Example: + * - When `type="popover"`, replaces Dialog with ``. + * - When `type="fullscreen"`, replaces Dialog with ``. + * - When `type="fullscreenTakeover"`, replaces Dialog with ``. + */ +function updateDialogChild( + path: NodePath +) { + let typePath = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'type') as NodePath | undefined; + let type = typePath?.node.value?.type === 'StringLiteral' ? typePath.node.value?.value : 'modal'; + let newComponent = 'Dialog'; + let props: t.JSXAttribute[] = []; + if (type === 'popover') { + newComponent = 'Popover'; + } else if (type === 'fullscreen' || type === 'fullscreenTakeover') { + newComponent = 'FullscreenDialog'; + if (type === 'fullscreenTakeover') { + props.push(t.jsxAttribute(t.jsxIdentifier('variant'), t.stringLiteral(type))); + } + } + + for (let prop of ['isDismissible', 'mobileType', 'hideArrow', 'placement', 'shouldFlip', 'isKeyboardDismissDisabled', 'containerPadding', 'offset', 'crossOffset']) { + let attr = path.get('openingElement').get('attributes').find(attr => attr.isJSXAttribute() && attr.node.name.name === prop) as NodePath | undefined; + if (attr) { + props.push(attr.node); + attr.remove(); + } + } + + typePath?.remove(); + + let localName = newComponent; + if (newComponent !== 'Dialog' && availableComponents.has(newComponent)) { + let program = path.findParent((p) => t.isProgram(p.node)) as NodePath; + localName = addComponentImport(program, newComponent); + } + + path.traverse({ + JSXElement(dialog) { + if (!t.isJSXIdentifier(dialog.node.openingElement.name) || getName(dialog, dialog.node.openingElement.name) !== 'Dialog') { + return; + } + + dialog.node.openingElement.name = t.jsxIdentifier(localName); + if (dialog.node.closingElement) { + dialog.node.closingElement.name = t.jsxIdentifier(localName); + } + + dialog.node.openingElement.attributes.push(...props); + } + }); +} + export const functionMap = { updatePropNameAndValue, updatePropValueAndAddNewProp, @@ -979,5 +1035,6 @@ export const functionMap = { updatePlacementToSingleValue, removeComponentIfWithinParent, updateAvatarSize, - updateLegacyLink + updateLegacyLink, + updateDialogChild }; From 65e3a52a39696c1bd62d7c641492bd417afd8857 Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Tue, 19 Nov 2024 16:33:39 -0800 Subject: [PATCH 5/5] Improve error message for missing Provider error (#7404) --- packages/@react-spectrum/provider/src/Provider.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/@react-spectrum/provider/src/Provider.tsx b/packages/@react-spectrum/provider/src/Provider.tsx index f86a7f64c07..a8b97ec0d38 100644 --- a/packages/@react-spectrum/provider/src/Provider.tsx +++ b/packages/@react-spectrum/provider/src/Provider.tsx @@ -198,7 +198,10 @@ const ProviderWrapper = React.forwardRef(function ProviderWrapper(props: Provide export function useProvider() { let context = useContext(Context); if (!context) { - throw new Error('No root provider found.'); + throw new Error( + 'No root provider found, please make sure your app is wrapped within a . ' + + 'Alternatively, this issue may be caused by duplicate packages, see https://github.com/adobe/react-spectrum/wiki/Frequently-Asked-Questions-(FAQs)#why-are-there-errors-after-upgrading-a-react-spectrum-package for more information.' + ); } return context; }