TrackedExpandableContext

HOC wrapping the given Component in a ExpandableContext, enriching it with the objectiv prop and automatically tracking visibility events when isVisible changes.

TrackedExpandableContext: <T>(props: T & {
objectiv: {
Component: ElementType | keyof ReactHTML,
id: string,
normalizeId?: boolean,
isVisible?: boolean
}
}) => JSX.Element

objectiv prop attributes

typedefault value
requiredComponentElementType | keyof ReactHTML
requiredidstring
optionalnormalizeIdbooleantrue
optionalisVisiblebooleanundefined

Returns

JSX.Element

Automatic Events

info

The isVisible state of a TrackedExpandableContext is ignored on mount. Only actual changes and tracked.

Usage example

Elements

import { TrackedExpandableContext } from '@objectiv/tracker-react';

<TrackedExpandableContext<ComponentProps<'ul'>>
objectiv={{
Component: 'ul',
id: 'list'
}}
>
...
</TrackedExpandableContext>

ID normalization

By default, all Tracked Context Components automatically normalize their Context identifiers to a kebab-cased format.

This can be disabled via the normalizeId option. This is useful when identifiers need to be preserved for cross-platform concerns or if they are standardized identifiers, e.g. a code from a backend API.

In this example the identifier, which would normally be main-menu, will be preserved as Main Menu:

import { TrackedExpandableContext } from '@objectiv/tracker-react';

<TrackedExpandableContext<ComponentProps<'ul'>>
objectiv={{
Component: 'ul',
id: 'Main Menu',
normalizeId: false
}}
>
...
</TrackedExpandableContext>

Components

The Component prop doesn't need to be a JSX Element. Actually, more often than not, it will probably be another Component.
Here is an example of how to wrap around a hypothetical Menu component.

import { Menu, MenuProps } from '../components';
import React, { ComponentProps } from 'react';
import { TrackedExpandableContext, TrackedShowableContextObjectivProp } from '@objectiv/tracker-react';

export type TrackedMenuProps = MenuProps & {
objectiv?: Omit<TrackedShowableContextObjectivProp, 'Component'>;
};

export const TrackedMenu = React.forwardRef<HTMLUListElement, TrackedMenuProps>(
({ objectiv, ...nativeProps }, ref) => (
<TrackedExpandableContext<ComponentProps<typeof Menu>>
{...nativeProps}
ref={ref}
objectiv={{
...objectiv,
Component: Menu,
id: objectiv?.id ?? 'menu'
}}
/>
)
);

This can now be used like this:

<TrackedMenu>
<MenuItem>Menu 1</MenuItem>
<MenuItem>Menu 2</MenuItem>
<MenuItem>Menu 3</MenuItem>
</TrackedMenu>

<TrackedMenu objectiv={{ id: 'menu-id' }}>
<MenuItem>Menu 1</MenuItem>
<MenuItem>Menu 2</MenuItem>
<MenuItem>Menu 3</MenuItem>
</TrackedMenu>

<TrackedMenu id={'menu-id'}>
<MenuItem>Menu 1</MenuItem>
<MenuItem>Menu 2</MenuItem>
<MenuItem>Menu 3</MenuItem>
</TrackedMenu>
Components how-to guides

Did you know ?

TrackedExpandableContext internally uses ExpandableContextWrapper.