UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

175 lines (174 loc) 6.36 kB
import * as React from 'react'; import type { PolymorphicForwardRefComponent } from '../../utils/index.js'; import { Text } from '../Typography/Text.js'; import type { FocusEntry, PanelsInstance, TriggerMapEntry } from './helpers.js'; type PanelsWrapperProps = { /** * Function that gets called when the active panel is changed. */ onActiveIdChange?: (newActiveId: string) => void; children: React.ReactNode; /** * Pass an instance created by `useInstance` to control the panels imperatively. * * @example * const panels = Panels.useInstance(); * <Panels instance={panels} /> */ instance?: PanelsInstance; }; export declare const PanelsWrapper: PolymorphicForwardRefComponent<"div", PanelsWrapperProps>; export declare const PanelsWrapperContext: React.Context<{ activePanelId: string | undefined; setActivePanelId: React.Dispatch<React.SetStateAction<string>>; /** * Simpler alternative to a full history stack. * * ``` * Record< * string, // Id of a panel * { * triggerId: string, // Id of the trigger element that points to this panel * panelId: string, // Id of the panel element in which the trigger is present * } * > * ``` */ triggers: Record<string, TriggerMapEntry>; setTriggers: React.Dispatch<React.SetStateAction<Record<string, TriggerMapEntry>>>; changeActivePanel: (newActiveId: string) => void; shouldFocus: FocusEntry; setShouldFocus: React.Dispatch<React.SetStateAction<FocusEntry>>; panels: React.MutableRefObject<Set<string>>; } | undefined>; type PanelProps = { id: string; }; type PanelTriggerProps = { for: string; children: React.ReactElement<any>; }; type PanelHeaderProps = { titleProps?: React.ComponentProps<typeof Text>; }; export declare const Panels: { /** * Component that manages the logic for layered panels. * It can be used anywhere to create layers. E.g. `Menu`, `InformationPanel`, `Popover`, etc. * * Requirements: * - The initial displayed Panel should be the first `Panel` in the `Panels.Wrapper`. * - A panel can have only one trigger pointing to it. i.e. out of all the triggers across all panels, * only one can point to a particular panel. * - The `Panels.Panel`s within the wrapper should be in the order of the navigation. E.g.: * ```jsx * <Panels.Wrapper> * <Panels.Panel id={root} /> // Must come before moreDetails since it contains the trigger to moreDetails * <Panels.Panel id={moreDetails}> // Must come after root since it is navigated to from root * </Panels.Wrapper> * ``` * * @example * <Panels.Wrapper as={Surface}> * <Panels.Panel * id={panelIdRoot} * as={Surface} * border={false} * elevation={0} * > * <Surface.Header as={Panels.Header}>Root</Surface.Header> * <Surface.Body as={List}> * <ListItem> * <Panels.Trigger for={panelIdMoreInfo}> * <ListItem.Action>More details</ListItem.Action> * </Panels.Trigger> * </ListItem> * </Surface.Body> * </Panels.Panel> * * <Panels.Panel * id={panelIdMoreInfo} * as={Surface} * border={false} * elevation={0} * > * <Surface.Header as={Panels.Header}>More details</Surface.Header> * <Surface.Body isPadded> * <Text>Content</Text> * </Surface.Body> * </Panels.Panel> * </Panels.Wrapper> */ Wrapper: PolymorphicForwardRefComponent<"div", PanelsWrapperProps>; /** * Takes an `id` and the panel content. * Match this `id` with a `Panels.Triggers`'s `for` prop to create a link between them. * * @example * <Panels.Panel id={panelIdRoot} as={Surface} border={false} elevation={0}> * <Surface.Header as={Panels.Header}>Root</Surface.Header> * <Surface.Body as={List}> * <ListItem> * <Panels.Trigger for={panelIdMoreInfo}> * <ListItem.Action>More details</ListItem.Action> * </Panels.Trigger> * </ListItem> * </Surface.Body> * </Panels.Panel> */ Panel: PolymorphicForwardRefComponent<"div", PanelProps>; /** * Wraps the clickable element and appends an `onClick` to change the active panel to the one specified in the `for` * prop. Also appends some attributes for accessibility. * * @example * <Panels.Trigger for={nextPanelId}> * <Button>go to next panel</Button> * </Panels.Trigger> * * @example * <ListItem> * <Panels.Trigger for={panelIdMoreInfo}> * <ListItem.Action>More details</ListItem.Action> * </Panels.Trigger> * </ListItem> */ Trigger: { (props: PanelTriggerProps): string | number | bigint | true | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null; displayName: string; }; /** * Required component to add an accessible name and also a back button (if previous panel exists) to the panel. * * @example * <Panels.Panel id={panelIdRoot}> * <Panels.Header>Root</Panels.Header> * … * </Panels.Panel> * * @example * <Panels.Panel * id={panelIdMoreInfo} * as={Surface} * border={false} * elevation={0} * > * <Surface.Header as={Panels.Header}>More details</Surface.Header> * <Surface.Body isPadded> * <Text>Content</Text> * </Surface.Body> * </Panels.Panel> */ Header: PolymorphicForwardRefComponent<"div", PanelHeaderProps>; /** * You can use methods from `Panels.useInstance()` to control the state programmatically. * * @example * const panels = Panels.useInstance(); * * <Button onClick={() => panels.goBack()}>Go back</Button> * <Panels.Wrapper instance={panels}>{…}</Panels.Wrapper>; */ useInstance: () => PanelsInstance; }; export {};