Skip to content

Hooks Primitive

Types Primitives


A collection of hooks for core primitives.

Hooks

  • useAugmentedRef: Allows using a forwarded ref as a value of useRef and allows adding properties to the ref.
  • useControllableState: Allows defaulting to an uncontrolled state and allows controlling the state from the parent.
  • useRelativePosition: Returns a style for an element relative to another element.

Installation

useAugmentedRef

Copy/paste the following code to ~/components/primitives/hooks/useAugmentedRef.tsx

useControllableState

Copy/paste the following code to ~/components/primitives/hooks/useControllableState.tsx

useRelativePosition

Copy/paste the following code to ~/components/primitives/hooks/useRelativePosition.tsx

Index

Copy/paste the following code to ~/components/primitives/hooks/index.ts

Usage

useAugmentedRef

import { useAugmentedRef } from '~/components/primitives/hooks';
import type { PressableRef, SlottablePressableProps } from '~/components/primitives/types';
const Thing = React.forwardRef<PressableRef, SlottablePressableProps>(
(props, ref) => {
const augmentedRef = useAugmentedRef({ ref });
React.useEffect(() => {
if (augmentedRef.current) {
// Do something with the augmented ref
}
}, []);
return (
<Pressable
ref={augmentedRef}
{...props}
/>
);
}
);

useControllableState

import { useControllableState } from '~/components/primitives/hooks';
import type { PressableRef, SlottablePressableProps } from '~/components/primitives/types';
const Thing = React.forwardRef<PressableRef, SlottablePressableProps & { defaultOpen?: boolean, open?: boolean, onOpenChange?: (open: boolean) => void }>(
({ defaultOpen, open: openProp, onOpenChange: onOpenChangeProp, onPress: onPressProp, ...props}, ref) => {
const [open = false, onOpenChange] = useControllableState({
prop: openProp,
defaultProp: defaultOpen,
onChange: onOpenChangeProp,
});
function onPress() {
onOpenChange(!open);
onPressProp?.();
}
return (
<Pressable
ref={augmentedRef}
onPress={onPress}
{...props}
/>
);
}
);

useRelativePosition

import { useRelativePosition } from '~/components/primitives/hooks';
import type { PositionedContentProps, SlottablePressableProps, ViewRef } from '~/components/primitives/types';
const Content = React.forwardRef<ViewRef, SlottableViewProps & PositionedContentProps>(
(
{
align = 'center',
side = 'top',
sideOffset = 0,
alignOffset = 0,
avoidCollisions = true,
onLayout: onLayoutProp,
insets,
style,
disablePositioningStyle,
...props
},
ref
) => {
const {
contentLayout,
setContentLayout,
triggerPosition,
} = useRootContext();
const positionStyle = useRelativePosition({
align,
avoidCollisions,
triggerPosition,
contentLayout,
alignOffset,
insets,
sideOffset,
side,
disablePositioningStyle,
});
function onLayout(event: LayoutChangeEvent) {
setContentLayout(event.nativeEvent.layout);
onLayoutProp?.(event);
}
return (
<View
ref={ref}
style={[positionStyle, style]}
onLayout={onLayout}
{...props}
/>
);
}
);

Props

useAugmentedRef

By default, children of all Portal components will be rendered as its own children.

PropTypeNote
ref*React.Ref<T>
methodsRecord<string, (…args: any[]) => any>Added methods to the forwardRef. Allows the parent component that passes the ref to call the added methods (optional)
depsArray<any>Dependency array: a list of all reactive values referenced in the mothods (optional)

useControllableState

PropTypeNote
propT | undefined(optional)
defaultPropT | undefined(optional)
onChange(state: T | undefined) => void(optional)

useRelativePosition

PropTypeNote
align*‘start’ | ‘center’ | ‘end’Horizontal alignment of content position relative to trigger
avoidCollisions*booleanPrevent content from going offscreen
triggerPosition*LayoutPosition | nullLayout position of the trigger
contentLayout*LayoutRectangle | nullLayout Size of the content
alignOffset*numberHorizontal offset
insets*LayoutRectangleWhen avoidCollisions is true, it prevents content from going over insets
sideOffset*numberVertical offset
side*‘top’ | ‘bottom’;Side alignment of content position relative to trigger
disablePositioningStyle*booleanCompletely disables styling returned from hook