Switch AccessibleButton and derivatives to using forwardRef (#12054)
* Prevent Cypress typechecking react-sdk components without strict mode This prevented us from switching to `forwardRef` in a bunch of places due to it behaving different with & without strict mode. Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update global.d.ts * Switch AccessibleButton and derivatives to using `forwardRef` Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add missing ref={ref} Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Ensure RefObjects are used consistently Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Re-add WysiwygAutocomplete displayname Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix forwardRef types Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add comments Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Remove unused export Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Readd comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate types & comments Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Improve comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
0a881e2123
commit
f632e2124f
@@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { HTMLAttributes, InputHTMLAttributes } from "react";
|
||||
import React, { forwardRef, FunctionComponent, HTMLAttributes, InputHTMLAttributes, Ref } from "react";
|
||||
import classnames from "classnames";
|
||||
|
||||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||
@@ -66,7 +66,6 @@ type DynamicElementProps<T extends keyof JSX.IntrinsicElements> = Partial<
|
||||
* Extends props accepted by the underlying element specified using the `element` prop.
|
||||
*/
|
||||
type Props<T extends keyof JSX.IntrinsicElements> = DynamicHtmlElementProps<T> & {
|
||||
inputRef?: React.Ref<Element>;
|
||||
/**
|
||||
* The base element type. "div" by default.
|
||||
*/
|
||||
@@ -101,22 +100,26 @@ interface RenderedElementProps extends React.InputHTMLAttributes<Element> {
|
||||
* as a button. Identifies the element as a button, setting proper tab
|
||||
* indexing and keyboard activation behavior.
|
||||
*
|
||||
* If a ref is passed, it will be forwarded to the rendered element as specified using the `element` prop.
|
||||
*
|
||||
* @param {Object} props react element properties
|
||||
* @returns {Object} rendered react
|
||||
*/
|
||||
export default function AccessibleButton<T extends keyof JSX.IntrinsicElements>({
|
||||
element = "div" as T,
|
||||
onClick,
|
||||
children,
|
||||
kind,
|
||||
disabled,
|
||||
inputRef,
|
||||
className,
|
||||
onKeyDown,
|
||||
onKeyUp,
|
||||
triggerOnMouseDown,
|
||||
...restProps
|
||||
}: Props<T>): JSX.Element {
|
||||
const AccessibleButton = forwardRef(function <T extends keyof JSX.IntrinsicElements>(
|
||||
{
|
||||
element = "div" as T,
|
||||
onClick,
|
||||
children,
|
||||
kind,
|
||||
disabled,
|
||||
className,
|
||||
onKeyDown,
|
||||
onKeyUp,
|
||||
triggerOnMouseDown,
|
||||
...restProps
|
||||
}: Props<T>,
|
||||
ref: Ref<HTMLElement>,
|
||||
): JSX.Element {
|
||||
const newProps: RenderedElementProps = restProps;
|
||||
if (disabled) {
|
||||
newProps["aria-disabled"] = true;
|
||||
@@ -170,7 +173,7 @@ export default function AccessibleButton<T extends keyof JSX.IntrinsicElements>(
|
||||
}
|
||||
|
||||
// Pass through the ref - used for keyboard shortcut access to some buttons
|
||||
newProps.ref = inputRef;
|
||||
newProps.ref = ref;
|
||||
|
||||
newProps.className = classnames("mx_AccessibleButton", className, {
|
||||
mx_AccessibleButton_hasKind: kind,
|
||||
@@ -180,11 +183,13 @@ export default function AccessibleButton<T extends keyof JSX.IntrinsicElements>(
|
||||
|
||||
// React.createElement expects InputHTMLAttributes
|
||||
return React.createElement(element, newProps, children);
|
||||
}
|
||||
});
|
||||
|
||||
AccessibleButton.defaultProps = {
|
||||
// Type assertion required due to forwardRef type workaround in react.d.ts
|
||||
(AccessibleButton as FunctionComponent).defaultProps = {
|
||||
role: "button",
|
||||
tabIndex: 0,
|
||||
};
|
||||
(AccessibleButton as FunctionComponent).displayName = "AccessibleButton";
|
||||
|
||||
AccessibleButton.displayName = "AccessibleButton";
|
||||
export default AccessibleButton;
|
||||
|
||||
Reference in New Issue
Block a user