Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(React): require react18 and replace useAriaId with React.useId #1213

Merged
merged 6 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@
"semver-compare": "^1.0.0"
},
"peerDependencies": {
"react": "17.x || 18.x",
"react-dom": "17.x || 18.x"
"react": "18.x",
"react-dom": "18.x"
},
"publishConfig": {
"registry": "https://registry.npmjs.org",
Expand Down
8 changes: 4 additions & 4 deletions src/__stories__/helpers.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import {useAriaId, useIsInverseVariant, Select, TextField, Checkbox, skinVars} from '..';
import {useIsInverseVariant, Select, TextField, Checkbox, skinVars} from '..';
import {isRunningAcceptanceTest} from '../utils/platform';

type Props = {
Expand Down Expand Up @@ -104,7 +104,7 @@ export const useCheckbox = (
defaultValue = false
): [boolean, React.ReactElement<any, typeof Checkbox>] => {
const [isEnabled, setIsEnabled] = React.useState(defaultValue);
const id = useAriaId();
const id = React.useId();
const checkbox = (
<Checkbox name={'checkbox-' + id} checked={isEnabled} onChange={setIsEnabled}>
{label}
Expand All @@ -131,10 +131,10 @@ export const useSelect = (
values: Array<string>
): [string, React.ReactNode] => {
const [value, setValue] = React.useState(defaultValue);
const ariaId = useAriaId();
const id = React.useId();
const select = (
<Select
name={ariaId}
name={id}
value={value}
onChangeValue={setValue}
label={label}
Expand Down
26 changes: 0 additions & 26 deletions src/__stories__/use-aria-id-story.tsx

This file was deleted.

5 changes: 2 additions & 3 deletions src/accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {getPrefixedDataAttributes} from './utils/dom';
import Divider from './divider';
import {Boxed} from './boxed';
import {useIsInverseVariant} from './theme-variant-context';
import {useAriaId} from './hooks';
import {CSSTransition} from 'react-transition-group';
import {isRunningAcceptanceTest} from './utils/platform';
import {sprinkles} from './sprinkles.css';
Expand Down Expand Up @@ -128,8 +127,8 @@ const AccordionItemContent = React.forwardRef<TouchableElement, AccordionItemCon
const itemRef = React.useRef<HTMLDivElement | null>(null);
const {index, toggle} = useAccordionContext();
const isInverse = useIsInverseVariant();
const labelId = useAriaId();
const panelId = useAriaId();
const labelId = React.useId();
const panelId = React.useId();

const [itemIndex, setItemIndex] = React.useState<number>();
const isOpen = itemIndex !== undefined && index?.includes(itemIndex);
Expand Down
7 changes: 0 additions & 7 deletions src/aria-id-getter-context.tsx

This file was deleted.

5 changes: 3 additions & 2 deletions src/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {SPACE} from './utils/keys';
import {useControlProps} from './form-context';
import Inline from './inline';
import {Text3} from './text';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import classnames from 'classnames';
import {getPrefixedDataAttributes} from './utils/dom';
import * as styles from './checkbox.css';
Expand Down Expand Up @@ -86,7 +86,8 @@ type ChildrenProps = {
};

const Checkbox = React.forwardRef<HTMLDivElement, RenderProps | ChildrenProps>((props, ref) => {
const labelId = useAriaId(props['aria-labelledby']);
const reactId = React.useId();
const labelId = props['aria-labelledby'] || reactId;
const ariaLabel = props['aria-label'];
const hasExternalLabel = ariaLabel || props['aria-labelledby'];

Expand Down
4 changes: 2 additions & 2 deletions src/counter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {BaseTouchable} from './touchable';
import IconSubtractRegular from './generated/mistica-icons/icon-subtract-regular';
import IconAddMoreRegular from './generated/mistica-icons/icon-add-more-regular';
import IconTrashCanRegular from './generated/mistica-icons/icon-trash-can-regular';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import classNames from 'classnames';
import ScreenReaderOnly from './screen-reader-only';
import * as tokens from './text-tokens';
Expand Down Expand Up @@ -84,7 +84,7 @@ const Counter: React.FC<Props> = ({
valueLabel,
}) => {
const variant = useThemeVariant();
const counterId = useAriaId();
const counterId = React.useId();
const {texts, t} = useTheme();

const minValue = min === undefined ? 0 : min;
Expand Down
5 changes: 3 additions & 2 deletions src/form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';
import * as React from 'react';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import {FormContext} from './form-context';
import classnames from 'classnames';
import {sprinkles} from './sprinkles.css';
Expand Down Expand Up @@ -47,7 +47,8 @@ const Form: React.FC<FormProps> = ({
const fieldRegistrations = React.useRef(new Map<string, FieldRegistration>());
const formRef = React.useRef<HTMLFormElement | null>(null);
const {texts, t} = useTheme();
const id = useAriaId(idProp);
const reactId = React.useId();
const id = idProp || reactId;

React.useEffect(() => {
/**
Expand Down
16 changes: 0 additions & 16 deletions src/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import * as React from 'react';
import ThemeContext from './theme-context';
import ScreenSizeContext from './screen-size-context';
import AriaIdGetterContext from './aria-id-getter-context';
import {listenResize} from './utils/dom';
import {isClientSide} from './utils/environment';
import {isEqual} from './utils/helpers';
Expand Down Expand Up @@ -131,21 +130,6 @@ export const useElementDimensions = ({includeMargins = false}: {includeMargins?:
return {width, height, ref};
};

export const useAriaId = (id?: string): string => {
const {useId} = useTheme();
// This useId should be stable, so the rules-of-hooks still apply
if (useId) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const generatedId = useId();
return id || generatedId;
} else {
// eslint-disable-next-line react-hooks/rules-of-hooks
const getAriaId = React.useContext(AriaIdGetterContext);
// eslint-disable-next-line react-hooks/rules-of-hooks
return React.useRef(id || getAriaId()).current;
}
};

export const useWindowSize = (): {
height: number;
width: number;
Expand Down
4 changes: 2 additions & 2 deletions src/icons/icon-success-vivo-new.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';
import * as React from 'react';
import {useAriaId, useTheme} from '../hooks';
import {useTheme} from '../hooks';
import {getAnimateCircleScaleInProps, getAnimateDrawLineProps} from '../utils/animation';

type Props = {
Expand All @@ -9,7 +9,7 @@ type Props = {

const IconSuccessVivoNew = ({size = 48}: Props): JSX.Element => {
const {platformOverrides} = useTheme();
const gradientId = useAriaId();
const gradientId = React.useId();

return (
<svg role="presentation" width={size} height={size} viewBox="0 0 64 64" fill="none">
Expand Down
4 changes: 2 additions & 2 deletions src/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {SkeletonAnimation} from './skeletons';
import {AspectRatioContainer} from './utils/aspect-ratio-support';
import {getPrefixedDataAttributes} from './utils/dom';
import {useIsInverseVariant} from './theme-variant-context';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import {VIVO_SKIN, VIVO_NEW_SKIN} from './skins/constants';
import {sprinkles} from './sprinkles.css';
import * as styles from './image.css';
Expand Down Expand Up @@ -166,7 +166,7 @@ export const ImageContent = React.forwardRef<HTMLImageElement, ImageProps>(
},
ref
) => {
const imageId = useAriaId();
const imageId = React.useId();
const imageRef = React.useRef<HTMLImageElement>();
const borderRadiusStyle = props.circular
? styles.circularBorderRadius
Expand Down
1 change: 0 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ export {
useTheme,
useScreenSize,
useElementDimensions,
useAriaId,
useWindowSize,
useWindowHeight,
useWindowWidth,
Expand Down
3 changes: 1 addition & 2 deletions src/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {Text3, Text2, Text1} from './text';
import Box from './box';
import Stack from './stack';
import Badge from './badge';
import {useAriaId} from './hooks';
import {useIsInverseVariant} from './theme-variant-context';
import IconChevron from './icons/icon-chevron';
import Switch from './switch-component';
Expand Down Expand Up @@ -341,7 +340,7 @@ const hasControlProps = (
};

const RowContent = React.forwardRef<TouchableElement, RowContentProps>((props, ref) => {
const titleId = useAriaId();
const titleId = React.useId();
const isInverse = useIsInverseVariant();
const {
asset,
Expand Down
4 changes: 2 additions & 2 deletions src/navigation-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ResponsiveLayout from './responsive-layout';
import Inline from './inline';
import Touchable, {BaseTouchable} from './touchable';
import {Text2, Text3} from './text';
import {useScreenSize, useTheme, useAriaId} from './hooks';
import {useScreenSize, useTheme} from './hooks';
import IconMenuRegular from './generated/mistica-icons/icon-menu-regular';
import IconCloseRegular from './generated/mistica-icons/icon-close-regular';
import IconChevronLeftRegular from './generated/mistica-icons/icon-chevron-left-regular';
Expand Down Expand Up @@ -157,7 +157,7 @@ export const MainNavigationBar: React.FC<MainNavigationBarProps> = ({
const {texts, isDarkMode, t} = useTheme();
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
const [menuTransitionState, setMenuTransitionState] = React.useState<MenuTransitionState>('closed');
const menuId = useAriaId();
const menuId = React.useId();
const shadowAlpha = isDarkMode ? 1 : 0.2;
const {isTabletOrSmaller} = useScreenSize();
const setModalState = useSetModalState();
Expand Down
4 changes: 2 additions & 2 deletions src/pin-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as React from 'react';
import Inline from './inline';
import * as textFieldStyles from './text-field-base.css';
import * as styles from './pin-field.css';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import ScreenReaderOnly from './screen-reader-only';
import {IntegerInput} from './integer-field';
import {useFieldProps} from './form-context';
Expand Down Expand Up @@ -310,7 +310,7 @@ const PinField = ({
onChange,
});

const otpLabelId = useAriaId();
const otpLabelId = React.useId();

return (
<div
Expand Down
5 changes: 3 additions & 2 deletions src/radio-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {combineRefs} from './utils/common';
import {Text3} from './text';
import Inline from './inline';
import classnames from 'classnames';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import {getPrefixedDataAttributes} from './utils/dom';
import * as styles from './radio-button.css';

Expand Down Expand Up @@ -64,7 +64,8 @@ const RadioButton: React.FC<PropsRender | PropsChildren> = ({
...rest
}) => {
const {disabled, selectedValue, focusableValue, select, selectNext, selectPrev} = useRadioContext();
const labelId = useAriaId(ariaLabelledby);
const reactId = React.useId();
const labelId = ariaLabelledby || reactId;
const ref = React.useRef<HTMLDivElement>(null);
const checked = value === selectedValue;
const tabIndex = focusableValue === value ? 0 : -1;
Expand Down
5 changes: 3 additions & 2 deletions src/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as React from 'react';
import classnames from 'classnames';
import {useForm} from './form-context';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import {DOWN, ENTER, ESC, SPACE, TAB, UP} from './utils/keys';
import {FieldContainer, HelperText, Label} from './text-field-components';
import ChevronDownRegular from './generated/mistica-icons/icon-chevron-down-regular';
Expand Down Expand Up @@ -76,7 +76,8 @@ const Select: React.FC<SelectProps> = ({
}>({});
const [tentativeValueState, setTentativeValueState] = React.useState<string>();
const lastElementSelectionScrollTop = React.useRef<number>(null);
const inputId = useAriaId(id);
const reactId = React.useId();
const inputId = id || reactId;
const {
rawValues,
setRawValue,
Expand Down
4 changes: 2 additions & 2 deletions src/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import classnames from 'classnames';
import * as React from 'react';
import * as styles from './sheet.css';
import FocusTrap from './focus-trap';
import {useAriaId, useDisableBodyScroll, useIsInViewport, useScreenSize, useTheme} from './hooks';
import {useDisableBodyScroll, useIsInViewport, useScreenSize, useTheme} from './hooks';
import {useSetModalStateEffect} from './modal-context-provider';
import {Portal} from './portal';
import {Text2, Text3, Text5} from './text';
Expand Down Expand Up @@ -170,7 +170,7 @@ const Sheet = React.forwardRef<HTMLDivElement, SheetProps>(({onClose, children,
const {texts, t} = useTheme();
const [modalState, dispatch] = React.useReducer(modalReducer, 'closed');
const initRef = React.useRef(false);
const modalTitleId = useAriaId();
const modalTitleId = React.useId();

const handleTransitionEnd = React.useCallback((ev: React.AnimationEvent | React.TransitionEvent) => {
// Don't trigger transitionEnd if the event is not triggered by the sheet element.
Expand Down
4 changes: 2 additions & 2 deletions src/spinner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as React from 'react';
import {getPlatform} from './utils/platform';
import FadeIn from './fade-in';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import * as styles from './spinner.css';
import {vars} from './skins/skin-contract.css';
import {useIsInverseVariant} from './theme-variant-context';
Expand All @@ -21,7 +21,7 @@ const Spinner: React.FC<Props> = ({color, delay = '500ms', size = 24, style, rol
const {texts, platformOverrides, t} = useTheme();
const isInverse = useIsInverseVariant();
color = color || (isInverse ? vars.colors.controlActivatedInverse : vars.colors.controlActivated);
const spinnerId = useAriaId();
const spinnerId = React.useId();
const withTitle = !rolePresentation;
const title = texts.loading || t(tokens.loading);
const content =
Expand Down
5 changes: 3 additions & 2 deletions src/switch-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {SPACE} from './utils/keys';
import {useControlProps} from './form-context';
import {Text3} from './text';
import Inline from './inline';
import {useAriaId, useTheme} from './hooks';
import {useTheme} from './hooks';
import {getPrefixedDataAttributes} from './utils/dom';
import * as styles from './switch-component.css';

Expand Down Expand Up @@ -52,7 +52,8 @@ type PropsChildren = {

const Switch: React.FC<PropsRender | PropsChildren> = (props) => {
const {isIos, isDarkMode} = useTheme();
const labelId = useAriaId(props['aria-labelledby']);
const reactId = React.useId();
const labelId = props['aria-labelledby'] || reactId;
const {defaultValue, value, onChange, focusableRef, disabled} = useControlProps({
name: props.name,
value: props.checked,
Expand Down
4 changes: 2 additions & 2 deletions src/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react';
import classnames from 'classnames';
import {BaseTouchable} from './touchable';
import ResponsiveLayout from './responsive-layout';
import {useAriaId, useElementDimensions, useTheme} from './hooks';
import {useElementDimensions, useTheme} from './hooks';
import {Text} from './text';
import {isRunningAcceptanceTest} from './utils/platform';
import {getPrefixedDataAttributes} from './utils/dom';
Expand Down Expand Up @@ -42,7 +42,7 @@ export type TabsProps = {

const Tabs: React.FC<TabsProps> = ({selectedIndex, onChange, tabs, dataAttributes}: TabsProps) => {
const {textPresets} = useTheme();
const id = useAriaId();
const id = React.useId();
const {ref} = useElementDimensions();
const animatedLineRef = React.useRef<HTMLDivElement>(null);
const scrollableContainerRef = React.useRef<HTMLDivElement>(null);
Expand Down
Loading
Loading