From c692276ed529b08d72067a1bfaab5abf44f22f9e Mon Sep 17 00:00:00 2001 From: Jeff Yates Date: Wed, 11 Dec 2024 15:02:19 -0600 Subject: [PATCH 1/9] [wb1812.3.migratewb] Migrate uses of IDProvider --- .../with-action-scheduler.stories.tsx | 11 +++++------ .../src/components/action-menu.tsx | 11 +++++------ .../src/components/multi-select.tsx | 11 +++++------ .../src/components/single-select.tsx | 11 +++++------ .../src/components/labeled-text-field.tsx | 7 +++---- .../wonder-blocks-form/src/components/text-field.tsx | 7 +++---- .../src/components/modal-header.tsx | 3 ++- .../src/components/one-pane-dialog.tsx | 7 +++---- .../wonder-blocks-popover/src/components/popover.tsx | 7 +++---- .../src/components/search-field.tsx | 7 +++---- 10 files changed, 37 insertions(+), 45 deletions(-) diff --git a/__docs__/wonder-blocks-timing/with-action-scheduler.stories.tsx b/__docs__/wonder-blocks-timing/with-action-scheduler.stories.tsx index a95601300..e6ef598a0 100644 --- a/__docs__/wonder-blocks-timing/with-action-scheduler.stories.tsx +++ b/__docs__/wonder-blocks-timing/with-action-scheduler.stories.tsx @@ -1,7 +1,6 @@ -/* eslint-disable import/no-deprecated */ import * as React from "react"; import {Meta} from "@storybook/react"; -import {IDProvider, View} from "@khanacademy/wonder-blocks-core"; +import {Id, View} from "@khanacademy/wonder-blocks-core"; import { Unmounter, @@ -30,7 +29,7 @@ export default { } as Meta; export const IncorrectUsage = () => ( - + {(id) => ( @@ -39,11 +38,11 @@ export const IncorrectUsage = () => ( )} - + ); export const CorrectUsage = () => ( - + {(id) => ( @@ -52,5 +51,5 @@ export const CorrectUsage = () => ( )} - + ); diff --git a/packages/wonder-blocks-dropdown/src/components/action-menu.tsx b/packages/wonder-blocks-dropdown/src/components/action-menu.tsx index 91011864e..d5db71ee4 100644 --- a/packages/wonder-blocks-dropdown/src/components/action-menu.tsx +++ b/packages/wonder-blocks-dropdown/src/components/action-menu.tsx @@ -2,8 +2,7 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; import {StyleSheet} from "aphrodite"; import { - // eslint-disable-next-line import/no-deprecated - IDProvider, + Id, type AriaProps, type StyleType, } from "@khanacademy/wonder-blocks-core"; @@ -256,7 +255,7 @@ export default class ActionMenu extends React.Component { const {disabled, menuText, opener, testId, id} = this.props; return ( - + {(uniqueOpenerId) => ( { }} )} - + ); } @@ -302,7 +301,7 @@ export default class ActionMenu extends React.Component { const items = this.getMenuItems(); return ( - + {(uniqueDropdownId) => ( { dropdownStyle={[styles.menuTopSpace, dropdownStyle]} /> )} - + ); } } diff --git a/packages/wonder-blocks-dropdown/src/components/multi-select.tsx b/packages/wonder-blocks-dropdown/src/components/multi-select.tsx index e749b05fe..43090a503 100644 --- a/packages/wonder-blocks-dropdown/src/components/multi-select.tsx +++ b/packages/wonder-blocks-dropdown/src/components/multi-select.tsx @@ -2,8 +2,7 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; import { - // eslint-disable-next-line import/no-deprecated - IDProvider, + Id, type AriaProps, type StyleType, } from "@khanacademy/wonder-blocks-core"; @@ -546,7 +545,7 @@ const MultiSelect = (props: Props) => { const menuText = getMenuText(allChildren); const dropdownOpener = ( - + {(uniqueOpenerId) => { return opener ? ( { ); }} - + ); return dropdownOpener; @@ -602,7 +601,7 @@ const MultiSelect = (props: Props) => { const isDisabled = numEnabledOptions === 0 || disabled; return ( - + {(uniqueDropdownId) => ( { disabled={isDisabled} /> )} - + ); }; diff --git a/packages/wonder-blocks-dropdown/src/components/single-select.tsx b/packages/wonder-blocks-dropdown/src/components/single-select.tsx index dc4660276..27a9fa429 100644 --- a/packages/wonder-blocks-dropdown/src/components/single-select.tsx +++ b/packages/wonder-blocks-dropdown/src/components/single-select.tsx @@ -2,8 +2,7 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; import { - // eslint-disable-next-line import/no-deprecated - IDProvider, + Id, type AriaProps, type StyleType, } from "@khanacademy/wonder-blocks-core"; @@ -444,7 +443,7 @@ const SingleSelect = (props: Props) => { : placeholder; const dropdownOpener = ( - + {(uniqueOpenerId) => { return opener ? ( { ); }} - + ); return dropdownOpener; @@ -498,7 +497,7 @@ const SingleSelect = (props: Props) => { const isDisabled = numEnabledOptions === 0 || disabled; return ( - + {(uniqueDropdownId) => ( { disabled={isDisabled} /> )} - + ); }; diff --git a/packages/wonder-blocks-form/src/components/labeled-text-field.tsx b/packages/wonder-blocks-form/src/components/labeled-text-field.tsx index b7ad9373a..d14a36b79 100644 --- a/packages/wonder-blocks-form/src/components/labeled-text-field.tsx +++ b/packages/wonder-blocks-form/src/components/labeled-text-field.tsx @@ -1,7 +1,6 @@ import * as React from "react"; -// eslint-disable-next-line import/no-deprecated -import {IDProvider, StyleType} from "@khanacademy/wonder-blocks-core"; +import {Id, StyleType} from "@khanacademy/wonder-blocks-core"; import FieldHeading from "./field-heading"; import TextField from "./text-field"; @@ -249,7 +248,7 @@ class LabeledTextField extends React.Component { } = this.props; return ( - + {(uniqueId) => ( { error={(!this.state.focused && this.state.error) || ""} /> )} - + ); } } diff --git a/packages/wonder-blocks-form/src/components/text-field.tsx b/packages/wonder-blocks-form/src/components/text-field.tsx index a7b97554b..d64930e61 100644 --- a/packages/wonder-blocks-form/src/components/text-field.tsx +++ b/packages/wonder-blocks-form/src/components/text-field.tsx @@ -1,8 +1,7 @@ import * as React from "react"; import {StyleSheet} from "aphrodite"; -// eslint-disable-next-line import/no-deprecated -import {IDProvider, addStyle} from "@khanacademy/wonder-blocks-core"; +import {Id, addStyle} from "@khanacademy/wonder-blocks-core"; import {border, color, mix, spacing} from "@khanacademy/wonder-blocks-tokens"; import {styles as typographyStyles} from "@khanacademy/wonder-blocks-typography"; @@ -246,7 +245,7 @@ const TextField = (props: PropsWithForwardRef) => { }; return ( - + {(uniqueId) => ( { {...otherProps} /> )} - + ); }; diff --git a/packages/wonder-blocks-modal/src/components/modal-header.tsx b/packages/wonder-blocks-modal/src/components/modal-header.tsx index dd1dc37fe..8225a63f1 100644 --- a/packages/wonder-blocks-modal/src/components/modal-header.tsx +++ b/packages/wonder-blocks-modal/src/components/modal-header.tsx @@ -71,7 +71,8 @@ type Props = Common | WithSubtitle | WithBreadcrumbs; * ModalHeader doesn’t have to have the `titleId` prop however this is * recommended. It should match the `aria-labelledby` prop of the * [ModalDialog](/#modaldialog) component. If you want to see an example of - * how to generate this ID, check [IDProvider](/#idprovider). + * how to generate this ID look at the `React.useId` hook documentation, o + * check [Id](/#id). * * **Implementation notes:** * diff --git a/packages/wonder-blocks-modal/src/components/one-pane-dialog.tsx b/packages/wonder-blocks-modal/src/components/one-pane-dialog.tsx index a68ed01bc..979751672 100644 --- a/packages/wonder-blocks-modal/src/components/one-pane-dialog.tsx +++ b/packages/wonder-blocks-modal/src/components/one-pane-dialog.tsx @@ -4,8 +4,7 @@ import {Breadcrumbs} from "@khanacademy/wonder-blocks-breadcrumbs"; import {MediaLayout} from "@khanacademy/wonder-blocks-layout"; import type {StyleType} from "@khanacademy/wonder-blocks-core"; -// eslint-disable-next-line import/no-deprecated -import {IDProvider} from "@khanacademy/wonder-blocks-core"; +import {Id} from "@khanacademy/wonder-blocks-core"; import ModalDialog from "./modal-dialog"; import ModalPanel from "./modal-panel"; import ModalHeader from "./modal-header"; @@ -197,7 +196,7 @@ export default class OnePaneDialog extends React.Component { return ( {({styles}) => ( - + {(uniqueId) => ( { /> )} - + )} ); diff --git a/packages/wonder-blocks-popover/src/components/popover.tsx b/packages/wonder-blocks-popover/src/components/popover.tsx index ab05e03c8..53f3068d5 100644 --- a/packages/wonder-blocks-popover/src/components/popover.tsx +++ b/packages/wonder-blocks-popover/src/components/popover.tsx @@ -1,8 +1,7 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; -// eslint-disable-next-line import/no-deprecated -import {IDProvider} from "@khanacademy/wonder-blocks-core"; +import {Id} from "@khanacademy/wonder-blocks-core"; import {TooltipPopper} from "@khanacademy/wonder-blocks-tooltip"; import {maybeGetPortalMountedModalHostElement} from "@khanacademy/wonder-blocks-modal"; @@ -390,7 +389,7 @@ export default class Popover extends React.Component { placement: placement, }} > - + {(uniqueId) => ( { {this.renderPortal(uniqueId, opened)} )} - + {dismissEnabled && opened && ( + {(uniqueId) => ( )} - + ); }); From 51447a63be1d3ef2b2496968f6bdf341fa8d73a2 Mon Sep 17 00:00:00 2001 From: Jeff Yates Date: Wed, 11 Dec 2024 15:07:16 -0600 Subject: [PATCH 2/9] [wb1812.3.migratewb] Update tests to drop need for checking scopes --- .../__tests__/labeled-text-field.test.tsx | 20 ++++++++----------- .../components/__tests__/text-area.test.tsx | 8 ++++---- .../components/__tests__/text-field.test.tsx | 8 ++++---- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/packages/wonder-blocks-form/src/components/__tests__/labeled-text-field.test.tsx b/packages/wonder-blocks-form/src/components/__tests__/labeled-text-field.test.tsx index d91bdc708..1e06b2b59 100644 --- a/packages/wonder-blocks-form/src/components/__tests__/labeled-text-field.test.tsx +++ b/packages/wonder-blocks-form/src/components/__tests__/labeled-text-field.test.tsx @@ -58,15 +58,13 @@ describe("LabeledTextField", () => { // Act render( {}} />); + const input = await screen.findByRole("textbox"); + const result = input.getAttribute("id"); // Assert // Since the generated id is unique, we cannot know what it will be. We - // only test if the id attribute starts with "uid-", then followed by - // "text-field-" as the scope assigned to IDProvider. - const input = await screen.findByRole("textbox"); - expect(input.getAttribute("id")).toMatch( - /uid-labeled-text-field.*-field/, - ); + // only that it ends with "-field". + expect(result).toMatch(/.*-field/); }); it("type prop is passed to input", async () => { @@ -207,16 +205,14 @@ describe("LabeledTextField", () => { // ariaDescribedby is not passed in />, ); + const input = await screen.findByRole("textbox"); + const result = input.getAttribute("aria-describedby"); // Assert // Since the generated aria-describedby is unique, // we cannot know what it will be. - // We only test if the aria-describedby attribute starts with - // "uid-" and ends with "-error". - const input = await screen.findByRole("textbox"); - expect(input.getAttribute("aria-describedby")).toMatch( - /^uid-.*-error$/, - ); + // We only test if the aria-describedby attribute ends with "-error". + expect(result).toMatch(/^.*-error$/); }); it("validate prop is called when input changes", async () => { diff --git a/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx b/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx index cfb7c6e94..089d061f8 100644 --- a/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx +++ b/packages/wonder-blocks-form/src/components/__tests__/text-area.test.tsx @@ -38,13 +38,13 @@ describe("TextArea", () => { // Act render(