@enact/ui
Version:
A collection of simplified unstyled cross-platform UI components for Enact
149 lines (131 loc) • 3.92 kB
TypeScript
// Type definitions for ui/Routable
import * as React from "react";
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;
export interface LinkBaseProps {}
/**
* A base component that is used to make a link.
*/
export class LinkBase extends React.Component<
Merge<React.HTMLProps<HTMLElement>, LinkBaseProps>
> {}
export interface RoutableConfig extends Object {
/**
* The event to listen to for path changes.
*
* This defines the actual name of the
property.
*/
navigate: string;
}
export interface RoutableProps {
/**
* Path to the active panel.
*
* May either be a URI-style path ( `'/app/home/settings'` ) or an array
of strings ( `['app', 'home', 'settings']` ).
*/
path: string | string[];
/**
* Called when navigating.
*
* The event object is decorated to add `path` .
*
* _NOTE_ : The actual name of this property is configured in the HOC config.
*/
navigate?: Function;
}
export function Routable<P>(
config: RoutableConfig,
Component: React.ComponentType<P> | string,
): React.ComponentType<P & RoutableProps>;
export function Routable<P>(
Component: React.ComponentType<P> | string,
): React.ComponentType<P & RoutableProps>;
export interface LinkProps extends Merge<LinkBaseProps, LinkableProps> {
/**
* The `path` to navigate that matches the path of the container.
*/
path: string;
/**
* Applies a disabled style and the control becomes non-interactive.
*/
disabled?: boolean;
}
/**
* A component that is used to make a link to navigate among components.
*
* In the following example, `Sample` would render `Main` with two Links for `About` and `FAQ` .
If `About` is clicked, the content of `About` would be displayed under `Main` .
*
* Example:
* ```
const Views = Routable({navigate: 'onNavigate'}, ({children}) => <div>{children}</div>);
const Main = () => (
<div>
<Link path="./about">About</Link>
<Link path="./faq">FAQ</Link>
</div>
);
const About = () => (<div>Greetings! We are Enact team.</div>);
const Faq = () => (<div>List of FAQ</div>);
const Sample = (props) => {
// use 'main' for the default path
const [path, nav] = useState('main');
// if onNavigate is called with a new path, update the state
const handleNavigate = useCallback((ev) => nav(ev.path), [nav]);
return (
<Views {...props} path={path} onNavigate={handleNavigate}>
<Route path="main" component={Main}>
<Route path="about" component={About} />
<Route path="faq" component={Faq} />
</Route>
</Views>
);
};
```
*/
export class Link extends React.Component<
Merge<React.HTMLProps<HTMLElement>, LinkProps>
> {}
export interface RouteProps {
/**
* The component to render when the `path` for this Route matches the path of the
container.
*/
component: string | React.ComponentType;
/**
* The name of the path segment.
*/
path: string;
}
/**
* Used with to define the `path` segment and the
`component` to render.
*
* `Route` elements can be nested to build multiple level paths.
*
* In the below example, `Panels` would render `SettingsPanel` with breadcrumbs to
navigate `AppPanel` and `HomePanel` .
*
* Example:
* ```
<Panels path="/app/home/settings" onSelectBreadcrumb={this.handleNavigate}>
<Route path="app" component={AppPanel}>
<Route path="home" component={HomePanel}>
<Route path="settings" component={SettingsPanel} />
</Route>
</Route>
<Route path="admin" component={AdminPanel} />
<Route path="help" component={HelpPanel} />
</Panels>
```
*/
export class Route extends React.Component<
Merge<React.HTMLProps<HTMLElement>, RouteProps>
> {}
export interface LinkableProps {}
export function Linkable<P>(
Component: React.ComponentType<P> | string,
): React.ComponentType<P & LinkableProps>;
export default Routable;