Skip to content

Commit

Permalink
[wb1812.1.deprecate] Mark ID stuff as deprecated (#2388)
Browse files Browse the repository at this point in the history
## Summary:
This is the first step in removing our custom ID utilities in favour of using the `useId` hook from React's API. This PR is not going to be merged/released on its own. Another PR will be coming to add an `Id` component that wraps `useId` so that there's an easier path for consumers to migrate.

The difficult bit is moving from the provider architecture that gives an ID factory, to the `useId`/`Id` approach. However, long term, it should simplify things greatly.

### Upgrade note:
Upgrading to this will cause deprecation notices in consuming code. If a lint rule is set up to block deprecated usage (which it probably is), then those errors will have to be suppressed. A find/replace may help in some circumstances, but this may also be a manual process. The alternative, of course, is to actually modify stuff to the new approach.

Issue: WB-1812

## Test plan:
`yarn test`
`yarn lint`

Author: somewhatabstract

Reviewers: jandrade

Required Reviewers:

Approved By: jandrade

Checks: ✅ Chromatic - Get results on regular PRs (ubuntu-latest, 20.x), ✅ Test / Test (ubuntu-latest, 20.x, 2/2), ✅ Test / Test (ubuntu-latest, 20.x, 1/2), ✅ Lint / Lint (ubuntu-latest, 20.x), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 20.x), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ⏭️  Chromatic - Skip on Release PR (changesets), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ gerald, ⏭️  dependabot

Pull Request URL: #2388
  • Loading branch information
somewhatabstract authored Dec 16, 2024
1 parent 2dbeb1d commit b6009b7
Show file tree
Hide file tree
Showing 32 changed files with 68 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .changeset/light-goats-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@khanacademy/wonder-blocks-core": major
"@khanacademy/wonder-blocks-search-field": patch
"@khanacademy/wonder-blocks-accordion": patch
"@khanacademy/wonder-blocks-dropdown": patch
"@khanacademy/wonder-blocks-popover": patch
"@khanacademy/wonder-blocks-testing": patch
"@khanacademy/wonder-blocks-tooltip": patch
"@khanacademy/wonder-blocks-switch": patch
"@khanacademy/wonder-blocks-modal": patch
"@khanacademy/wonder-blocks-form": patch
---

Deprecate the ID provider and unique ID utilities
1 change: 1 addition & 0 deletions __docs__/wonder-blocks-core/id-provider.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";
import type {Meta, StoryObj} from "@storybook/react";

Expand Down
1 change: 1 addition & 0 deletions __docs__/wonder-blocks-core/unique-id-provider.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";
import type {Meta, StoryObj} from "@storybook/react";

Expand Down
1 change: 1 addition & 0 deletions __docs__/wonder-blocks-core/use-unique-id.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";

import {Meta} from "@storybook/react";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";
import {Meta} from "@storybook/react";
import {IDProvider, View} from "@khanacademy/wonder-blocks-core";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from "react";
import {StyleSheet} from "aphrodite";
import type {StyleDeclaration} from "aphrodite";

// eslint-disable-next-line import/no-deprecated
import {useUniqueIdWithMock, View} from "@khanacademy/wonder-blocks-core";
import * as tokens from "@khanacademy/wonder-blocks-tokens";
import {Body} from "@khanacademy/wonder-blocks-typography";
Expand Down Expand Up @@ -203,6 +204,7 @@ const AccordionSection = React.forwardRef(function AccordionSection(

const controlledMode = expanded !== undefined && onToggle;

// eslint-disable-next-line import/no-deprecated
const ids = useUniqueIdWithMock();
const sectionId = id ?? ids.get("accordion-section");
// We need an ID for the header so that the content section's
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";
import {render} from "@testing-library/react";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import {render} from "@testing-library/react";
Expand Down
3 changes: 3 additions & 0 deletions packages/wonder-blocks-core/src/components/id-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";

import UniqueIDProvider from "./unique-id-provider";
Expand Down Expand Up @@ -54,6 +55,8 @@ type Props = {
* </IDProvider>
* ```
*
* @deprecated Use `useId` for your ID needs. If you are in a class-based
* component and cannot use hooks, then use the `Id` component.
*/
export default class IDProvider extends React.Component<Props> {
static defaultId = "wb-id";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";

import InitialFallback from "./initial-fallback";
Expand Down Expand Up @@ -69,6 +70,9 @@ type Props = {
* )}
* </UniqueIDProvider>
* ```
*
* @deprecated Use `useId` for your ID needs. If you are in a class-based
* component and cannot use hooks, then use the `Id` component.
*/
export default class UniqueIDProvider extends React.Component<Props> {
// @ts-expect-error [FEI-5019] - TS2564 - Property '_idFactory' has no initializer and is not definitely assigned in the constructor.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import * as React from "react";
import {render} from "@testing-library/react";
import {renderHookStatic} from "@khanacademy/wonder-blocks-testing-core";
Expand Down
7 changes: 7 additions & 0 deletions packages/wonder-blocks-core/src/hooks/use-unique-id.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import {useRef} from "react";

import {useRenderState} from "./use-render-state";
Expand All @@ -9,6 +10,9 @@ import {RenderState} from "../components/render-state-context";
import type {IIdentifierFactory} from "../util/types";

/**
* @deprecated Use `useId` for your ID needs. If you are in a class-based
* component and cannot use hooks, then use the `Id` component.
*
* Returns a unique identifier factory. If the parent component hasn't
* been mounted yet, the global SsrIDFactory will be returned until the
* component becomes mounted.
Expand All @@ -32,6 +36,9 @@ export const useUniqueIdWithMock = (scope?: string): IIdentifierFactory => {
};

/**
* @deprecated Use `useId` for your ID needs. If you are in a class-based
* component and cannot use hooks, then use the `Id` component.
*
* Returns a unique identifier factory. If the parent component hasn't
* been mounted yet, null will be returned.
*
Expand Down
2 changes: 2 additions & 0 deletions packages/wonder-blocks-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {
AriaProps,
// eslint-disable-next-line import/no-deprecated
IIdentifierFactory,
StyleType,
PropsFor,
Expand Down Expand Up @@ -27,4 +28,5 @@ export {RenderStateRoot} from "./components/render-state-root";
export {RenderState} from "./components/render-state-context";
export type {AriaRole, AriaAttributes} from "./util/aria-types";

// eslint-disable-next-line import/no-deprecated
export type {AriaProps, IIdentifierFactory, StyleType, PropsFor};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import UniqueIDFactory from "../unique-id-factory";

describe("UniqueIDFactory", () => {
Expand Down
3 changes: 3 additions & 0 deletions packages/wonder-blocks-core/src/util/ssr-id-factory.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable import/no-deprecated */
import type {IIdentifierFactory} from "./types";

/**
Expand All @@ -9,6 +10,8 @@ import type {IIdentifierFactory} from "./types";
*
* The identifiers are not guaranteed to be unique, but they will match between
* server and the first client render.
* @deprecated Use `useId` for your ID needs. If you are in a class-based
* component and cannot use hooks, then use the `Id` component.
*/
class SsrIDFactory implements IIdentifierFactory {
static Default: IIdentifierFactory = new SsrIDFactory();
Expand Down
2 changes: 2 additions & 0 deletions packages/wonder-blocks-core/src/util/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export type TextViewSharedProps = {

/**
* Interface implemented by types that can provide identifiers.
* @deprecated Use `useId` for your ID needs. If you are in a class-based
* component and cannot use hooks, then use the `Id` component.
*/
export interface IIdentifierFactory {
get(id: string): string;
Expand Down
4 changes: 4 additions & 0 deletions packages/wonder-blocks-core/src/util/unique-id-factory.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
/* eslint-disable import/no-deprecated */
import type {IIdentifierFactory} from "./types";

/**
* This is NOT for direct use. Instead, see the UniqueIDProvider component.
*
* Implements IIdentifierFactory to provide unique identifiers.
*
* @deprecated Use `useId` for your ID needs. If you are in a class-based
* component and cannot use hooks, then use the `Id` component.
*/
export default class UniqueIDFactory implements IIdentifierFactory {
_uniqueFactoryName: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +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,
type AriaProps,
type StyleType,
Expand Down
2 changes: 2 additions & 0 deletions packages/wonder-blocks-dropdown/src/components/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import xIcon from "@phosphor-icons/core/regular/x.svg";

import {
StyleType,
// eslint-disable-next-line import/no-deprecated
useUniqueIdWithMock,
View,
} from "@khanacademy/wonder-blocks-core";
Expand Down Expand Up @@ -175,6 +176,7 @@ export default function Combobox({
testId,
value = "",
}: Props) {
// eslint-disable-next-line import/no-deprecated
const ids = useUniqueIdWithMock("combobox");
const uniqueId = id ?? ids.get("listbox");
// Ref to the combobox input element.
Expand Down
2 changes: 2 additions & 0 deletions packages/wonder-blocks-dropdown/src/components/listbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from "react";
import {StyleSheet} from "aphrodite";
import {
StyleType,
// eslint-disable-next-line import/no-deprecated
useUniqueIdWithMock,
View,
} from "@khanacademy/wonder-blocks-core";
Expand Down Expand Up @@ -103,6 +104,7 @@ function StandaloneListbox(props: Props) {
"aria-labelledby": ariaLabelledby,
} = props;

// eslint-disable-next-line import/no-deprecated
const ids = useUniqueIdWithMock("listbox");
const uniqueId = id ?? ids.get("id");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from "react";
import * as ReactDOM from "react-dom";

import {
// eslint-disable-next-line import/no-deprecated
IDProvider,
type AriaProps,
type StyleType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from "react";
import * as ReactDOM from "react-dom";

import {
// eslint-disable-next-line import/no-deprecated
IDProvider,
type AriaProps,
type StyleType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from "react";
import {StyleSheet} from "aphrodite";

// eslint-disable-next-line import/no-deprecated
import {View, UniqueIDProvider} from "@khanacademy/wonder-blocks-core";
import {Strut} from "@khanacademy/wonder-blocks-layout";
import {color, spacing} from "@khanacademy/wonder-blocks-tokens";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from "react";

// eslint-disable-next-line import/no-deprecated
import {IDProvider, StyleType} from "@khanacademy/wonder-blocks-core";

import FieldHeading from "./field-heading";
Expand Down
2 changes: 2 additions & 0 deletions packages/wonder-blocks-form/src/components/text-area.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {StyleSheet} from "aphrodite";
import {
AriaProps,
StyleType,
// eslint-disable-next-line import/no-deprecated
useUniqueIdWithMock,
addStyle,
View,
Expand Down Expand Up @@ -244,6 +245,7 @@ const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(

const hasError = error || !!errorMessage;

// eslint-disable-next-line import/no-deprecated
const ids = useUniqueIdWithMock("text-area");
const uniqueId = id ?? ids.get("id");

Expand Down
1 change: 1 addition & 0 deletions packages/wonder-blocks-form/src/components/text-field.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +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 {border, color, mix, spacing} from "@khanacademy/wonder-blocks-tokens";
import {styles as typographyStyles} from "@khanacademy/wonder-blocks-typography";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +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 ModalDialog from "./modal-dialog";
import ModalPanel from "./modal-panel";
Expand Down
1 change: 1 addition & 0 deletions packages/wonder-blocks-popover/src/components/popover.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +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 {TooltipPopper} from "@khanacademy/wonder-blocks-tooltip";
import {maybeGetPortalMountedModalHostElement} from "@khanacademy/wonder-blocks-modal";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import xIcon from "@phosphor-icons/core/regular/x.svg";
import magnifyingGlassIcon from "@phosphor-icons/core/bold/magnifying-glass-bold.svg";

import {styles as typographyStyles} from "@khanacademy/wonder-blocks-typography";
// eslint-disable-next-line import/no-deprecated
import {View, IDProvider} from "@khanacademy/wonder-blocks-core";
import IconButton from "@khanacademy/wonder-blocks-icon-button";
import {TextField} from "@khanacademy/wonder-blocks-form";
Expand Down
2 changes: 2 additions & 0 deletions packages/wonder-blocks-switch/src/components/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
AriaProps,
View,
addStyle,
// eslint-disable-next-line import/no-deprecated
useUniqueIdWithMock,
} from "@khanacademy/wonder-blocks-core";
import {PhosphorIcon} from "@khanacademy/wonder-blocks-icon";
Expand Down Expand Up @@ -69,6 +70,7 @@ const SwitchCore = React.forwardRef(function SwitchCore(
testId,
} = props;

// eslint-disable-next-line import/no-deprecated
const ids = useUniqueIdWithMock("labeled-field");
const uniqueId = id ?? ids.get("labeled-field-id");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe("SSR.adapter", () => {
it("should enable harnessing of components that require RenderStateRoot", () => {
// Arrange
const ComponentNeedsSsr = (props: any) => {
// eslint-disable-next-line import/no-deprecated
const idf = WBCore.useUniqueIdWithoutMock();
return <div>{idf?.get("my-id")}</div>;
};
Expand Down
1 change: 1 addition & 0 deletions packages/wonder-blocks-tooltip/src/components/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import * as React from "react";
import * as ReactDOM from "react-dom";

import {
// eslint-disable-next-line import/no-deprecated
UniqueIDProvider,
IIdentifierFactory,
} from "@khanacademy/wonder-blocks-core";
Expand Down

0 comments on commit b6009b7

Please sign in to comment.