Skip to content

Commit

Permalink
Forward refs to most components (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandhose authored Aug 2, 2023
1 parent 33d0d8e commit f9fe675
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 73 deletions.
27 changes: 14 additions & 13 deletions src/components/ActionControl/ActionControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ type ActionControlProps = {
disabled?: boolean;
} & React.ComponentProps<typeof Control>;

export const ActionControl: React.FC<PropsWithChildren<ActionControlProps>> = ({
children,
Icon,
className,
actionLabel,
onActionClick,
...props
}) => {
export const ActionControl = React.forwardRef<
HTMLInputElement,
PropsWithChildren<ActionControlProps>
>(function ActionControl(
{ children, Icon, className, actionLabel, onActionClick, ...props },
ref,
) {
const id = useId();
const classes = classnames(styles.actioncontrol, className);
return (
<div className={classes}>
<Control
ref={ref}
{...props}
className={styles.input}
id={id}
Expand All @@ -60,16 +60,17 @@ export const ActionControl: React.FC<PropsWithChildren<ActionControlProps>> = ({
/>
</div>
);
};
});

export const StandaloneActionControl: React.FC<
export const StandaloneActionControl = React.forwardRef<
HTMLInputElement,
PropsWithChildren<ActionControlProps>
> = (props) => {
>(function StandaloneActionControl(props, ref) {
return (
<Root>
<Field name="action">
<ActionControl {...props} />
<ActionControl ref={ref} {...props} />
</Field>
</Root>
);
};
});
16 changes: 9 additions & 7 deletions src/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ type CheckboxProps = {
onMouseDown?: (e: React.MouseEvent<HTMLInputElement, MouseEvent>) => void;
} & React.ComponentPropsWithoutRef<"input">;

export const Checkbox: React.FC<PropsWithChildren<CheckboxProps>> = ({
kind = "primary",
className,
onMouseDown,
...props
}) => {
export const Checkbox = React.forwardRef<
HTMLInputElement,
PropsWithChildren<CheckboxProps>
>(function Checkbox(
{ kind = "primary", className, onMouseDown, ...props },
ref,
) {
const classes = classnames(styles.checkbox, className);
return (
<div className={classes} data-kind={kind}>
<input
ref={ref}
{...props}
type="checkbox"
onMouseDown={(e) => {
Expand All @@ -49,4 +51,4 @@ export const Checkbox: React.FC<PropsWithChildren<CheckboxProps>> = ({
</div>
</div>
);
};
});
12 changes: 6 additions & 6 deletions src/components/Form/Control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ type ControlProps = {
* Thin wrapper around Radix UI Control component
* https://www.radix-ui.com/docs/primitives/components/form#control
*/
export const Control: React.FC<PropsWithChildren<ControlProps>> = ({
children,
...props
}) => {
export const Control = React.forwardRef<
HTMLInputElement,
PropsWithChildren<ControlProps>
>(function Control({ children, ...props }, ref) {
const classes = classNames(styles.control, props.className);
return (
<RadixControl {...props} className={classes}>
<RadixControl ref={ref} {...props} className={classes}>
{children}
</RadixControl>
);
};
});
8 changes: 5 additions & 3 deletions src/components/Form/Controls/Password/Password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,17 @@ const hideState = {
* Thin wrapper around Radix UI Control component
* https://www.radix-ui.com/docs/primitives/components/form#control
*/
export const PasswordControl: React.FC<
export const PasswordControl = React.forwardRef<
HTMLInputElement,
PropsWithChildren<React.ComponentProps<typeof Control>>
> = (props) => {
>(function PasswordControl(props, ref) {
const [{ icon, label, type }, togglePasswordVisibility] = useReducer(
(state) => (!state.isHidden ? showState : hideState),
showState,
);
return (
<ActionControl
ref={ref}
{...props}
Icon={icon}
// TODO: Replace with a function that deal with i18n of those values
Expand All @@ -56,4 +58,4 @@ export const PasswordControl: React.FC<
type={type}
/>
);
};
});
12 changes: 6 additions & 6 deletions src/components/Form/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ type FieldProps = {
* Thin wrapper around Radix UI Field component
* https://www.radix-ui.com/docs/primitives/components/form#field
*/
export const Field: React.FC<PropsWithChildren<FieldProps>> = ({
children,
...props
}) => {
export const Field = React.forwardRef<
HTMLDivElement,
PropsWithChildren<FieldProps>
>(function Field({ children, ...props }, ref) {
const classes = classNames(styles.field, props.className);
return (
<RadixField {...props} className={classes}>
<RadixField ref={ref} {...props} className={classes}>
{children}
</RadixField>
);
};
});
12 changes: 6 additions & 6 deletions src/components/Form/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ type LabelProps = {
* Thin wrapper around Radix UI Label component
* https://www.radix-ui.com/docs/primitives/components/form#label
*/
export const Label: React.FC<PropsWithChildren<LabelProps>> = ({
children,
...props
}) => {
export const Label = React.forwardRef<
HTMLLabelElement,
PropsWithChildren<LabelProps>
>(function Label({ children, ...props }, ref) {
const classes = classNames(styles.label, props.className);
return (
<RadixLabel {...props} className={classes}>
<RadixLabel ref={ref} {...props} className={classes}>
{children}
</RadixLabel>
);
};
});
12 changes: 6 additions & 6 deletions src/components/Form/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ type MessageProps = {
* Thin wrapper around Radix UI Message component
* https://www.radix-ui.com/docs/primitives/components/form#message
*/
export const Message: React.FC<PropsWithChildren<MessageProps>> = ({
children,
...props
}) => {
export const Message = React.forwardRef<
HTMLSpanElement,
PropsWithChildren<MessageProps>
>(function Message({ children, ...props }, ref) {
const classes = classNames(styles.message, props.className);
return (
<RadixMessage {...props} className={classes}>
<RadixMessage ref={ref} {...props} className={classes}>
{/* Pending to be replaced by the alert component, see
https://github.com/vector-im/compound-web/pull/6 */}
{children}
</RadixMessage>
);
};
});
12 changes: 6 additions & 6 deletions src/components/Form/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ type RootProps = {
* Thin wrapper around Radix UI Root component
* https://www.radix-ui.com/docs/primitives/components/form#root
*/
export const Root: React.FC<PropsWithChildren<RootProps>> = ({
children,
...props
}) => {
export const Root = React.forwardRef<
HTMLFormElement,
PropsWithChildren<RootProps>
>(function Root({ children, ...props }, ref) {
const classes = classNames(styles.root, props.className);
return (
<RadixRoot {...props} className={classes}>
<RadixRoot ref={ref} {...props} className={classes}>
{children}
</RadixRoot>
);
};
});
13 changes: 6 additions & 7 deletions src/components/Link/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ type LinkProps = {
kind?: "primary" | "critical";
} & Omit<React.HTMLProps<HTMLAnchorElement>, "rel">;

export const Link: React.FC<PropsWithChildren<LinkProps>> = ({
children,
className,
kind = "primary",
...props
}) => {
export const Link = React.forwardRef<
HTMLAnchorElement,
PropsWithChildren<LinkProps>
>(function Link({ children, className, kind = "primary", ...props }, ref) {
return (
<a
ref={ref}
{...props}
rel="noreferrer noopener"
className={classNames(styles.link, className)}
Expand All @@ -39,4 +38,4 @@ export const Link: React.FC<PropsWithChildren<LinkProps>> = ({
{children}
</a>
);
};
});
13 changes: 6 additions & 7 deletions src/components/Radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,15 @@ type RadioProps = {
/**
* Radio form control
*/
export const Radio: React.FC<PropsWithChildren<RadioProps>> = ({
kind = "primary",
className,
onMouseDown,
...props
}) => {
export const Radio = React.forwardRef<
HTMLInputElement,
PropsWithChildren<RadioProps>
>(function Radio({ kind = "primary", className, onMouseDown, ...props }, ref) {
const classes = classnames(styles.radio, className);
return (
<div className={classes} data-kind={kind}>
<input
ref={ref}
{...props}
type="radio"
onMouseDown={(e) => {
Expand All @@ -49,4 +48,4 @@ export const Radio: React.FC<PropsWithChildren<RadioProps>> = ({
<div className={styles["radio-ui"]} />
</div>
);
};
});
12 changes: 6 additions & 6 deletions src/components/Toggle/Toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ type ToggleProps = {
* Standalone toggle component to be used with a Radix form control
* See https://www.radix-ui.com/docs/primitives/components/form#composing-with-your-own-components
*/
export const Toggle: React.FC<PropsWithChildren<ToggleProps>> = ({
className,
onMouseDown,
...props
}) => {
export const Toggle = React.forwardRef<
HTMLInputElement,
PropsWithChildren<ToggleProps>
>(function Toggle({ className, onMouseDown, ...props }, ref) {
const classes = classnames(styles.toggle, className);
return (
<div className={classes}>
<input
ref={ref}
{...props}
type="checkbox"
onMouseDown={(e) => {
Expand All @@ -48,4 +48,4 @@ export const Toggle: React.FC<PropsWithChildren<ToggleProps>> = ({
<div className={styles["toggle-ui"]} />
</div>
);
};
});

0 comments on commit f9fe675

Please sign in to comment.