@vx-oss/user
Version:
Flexible User Profile Component.
69 lines (66 loc) • 1.73 kB
JavaScript
"use client";
// src/use-user.ts
import { useMemo, useCallback } from "react";
import { useFocusRing } from "@react-aria/focus";
import { user } from "@vx-oss/theme";
import { clsx, dataAttr, mergeProps } from "@vx-oss/shared-utils";
import { filterDOMProps } from "@vx-oss/react-utils";
import { useDOMRef } from "@vx-oss/react-utils";
function useUser(props) {
const {
as,
ref,
name,
description,
className,
classNames,
isFocusable = false,
avatarProps: userAvatarProps = {},
...otherProps
} = props;
const avatarProps = {
isFocusable: false,
...userAvatarProps
};
const Component = as || "div";
const shouldFilterDOMProps = typeof Component === "string";
const domRef = useDOMRef(ref);
const { isFocusVisible, isFocused, focusProps } = useFocusRing({});
const canBeFocused = useMemo(() => {
return isFocusable || as === "button";
}, [isFocusable, as]);
const slots = useMemo(() => user(), []);
const baseStyles = clsx(classNames == null ? void 0 : classNames.base, className);
const getUserProps = useCallback(
() => ({
ref: domRef,
tabIndex: canBeFocused ? 0 : -1,
"data-focus-visible": dataAttr(isFocusVisible),
"data-focus": dataAttr(isFocused),
className: slots.base({
class: baseStyles
}),
...mergeProps(
filterDOMProps(otherProps, {
enabled: shouldFilterDOMProps
}),
canBeFocused ? focusProps : {}
)
}),
[canBeFocused, slots, baseStyles, focusProps, otherProps]
);
return {
Component,
className,
slots,
name,
description,
classNames,
baseStyles,
avatarProps,
getUserProps
};
}
export {
useUser
};