// 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;
