typescript src/tabs
, src/typography
(#491)
* first iteration * tabs generic - remove as from typography * typography using React.component function * comma mistake * ... * review + add back `as` option for typography. * linter * quick fix * us location descriptor
This commit is contained in:
parent
1dfffce606
commit
c09380644b
4 changed files with 122 additions and 87 deletions
|
@ -15,6 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { TabContainer, TabItem } from "./Tabs";
|
import { TabContainer, TabItem } from "./Tabs";
|
||||||
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
|
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
|
||||||
import { ReactComponent as VideoIcon } from "../icons/Video.svg";
|
import { ReactComponent as VideoIcon } from "../icons/Video.svg";
|
||||||
|
@ -29,7 +30,7 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Tabs = () => (
|
export const Tabs: React.FC<{}> = () => (
|
||||||
<TabContainer>
|
<TabContainer>
|
||||||
<TabItem
|
<TabItem
|
||||||
title={
|
title={
|
|
@ -17,19 +17,28 @@ limitations under the License.
|
||||||
import React, { useRef } from "react";
|
import React, { useRef } from "react";
|
||||||
import { useTabList, useTab, useTabPanel } from "@react-aria/tabs";
|
import { useTabList, useTab, useTabPanel } from "@react-aria/tabs";
|
||||||
import { Item } from "@react-stately/collections";
|
import { Item } from "@react-stately/collections";
|
||||||
import { useTabListState } from "@react-stately/tabs";
|
import { useTabListState, TabListState } from "@react-stately/tabs";
|
||||||
import styles from "./Tabs.module.css";
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import { AriaTabPanelProps, TabListProps } from "@react-types/tabs";
|
||||||
|
import { Node } from "@react-types/shared";
|
||||||
|
|
||||||
export function TabContainer(props) {
|
import styles from "./Tabs.module.css";
|
||||||
const state = useTabListState(props);
|
|
||||||
const ref = useRef();
|
interface TabContainerProps<T> extends TabListProps<T> {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TabContainer<T extends object>(
|
||||||
|
props: TabContainerProps<T>
|
||||||
|
): JSX.Element {
|
||||||
|
const state = useTabListState<T>(props);
|
||||||
|
const ref = useRef<HTMLUListElement>();
|
||||||
const { tabListProps } = useTabList(props, state, ref);
|
const { tabListProps } = useTabList(props, state, ref);
|
||||||
return (
|
return (
|
||||||
<div className={classNames(styles.tabContainer, props.className)}>
|
<div className={classNames(styles.tabContainer, props.className)}>
|
||||||
<ul {...tabListProps} ref={ref} className={styles.tabList}>
|
<ul {...tabListProps} ref={ref} className={styles.tabList}>
|
||||||
{[...state.collection].map((item) => (
|
{[...state.collection].map((item) => (
|
||||||
<Tab key={item.key} item={item} state={state} />
|
<Tab item={item} state={state} />
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<TabPanel key={state.selectedItem?.key} state={state} />
|
<TabPanel key={state.selectedItem?.key} state={state} />
|
||||||
|
@ -37,9 +46,14 @@ export function TabContainer(props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Tab({ item, state }) {
|
interface TabProps<T> {
|
||||||
|
item: Node<T>;
|
||||||
|
state: TabListState<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Tab<T>({ item, state }: TabProps<T>): JSX.Element {
|
||||||
const { key, rendered } = item;
|
const { key, rendered } = item;
|
||||||
const ref = useRef();
|
const ref = useRef<HTMLLIElement>();
|
||||||
const { tabProps } = useTab({ key }, state, ref);
|
const { tabProps } = useTab({ key }, state, ref);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -56,8 +70,12 @@ function Tab({ item, state }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabPanel({ state, ...props }) {
|
interface TabPanelProps<T> extends AriaTabPanelProps {
|
||||||
const ref = useRef();
|
state: TabListState<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function TabPanel<T>({ state, ...props }: TabPanelProps<T>): JSX.Element {
|
||||||
|
const ref = useRef<HTMLDivElement>();
|
||||||
const { tabPanelProps } = useTabPanel(props, state, ref);
|
const { tabPanelProps } = useTabPanel(props, state, ref);
|
||||||
return (
|
return (
|
||||||
<div {...tabPanelProps} ref={ref} className={styles.tabPanel}>
|
<div {...tabPanelProps} ref={ref} className={styles.tabPanel}>
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { Headline, Title, Subtitle, Body, Caption, Micro } from "./Typography";
|
import { Headline, Title, Subtitle, Body, Caption, Micro } from "./Typography";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -24,7 +25,7 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Typography = () => (
|
export const Typography: React.FC<{}> = () => (
|
||||||
<>
|
<>
|
||||||
<Headline>Headline Semi Bold</Headline>
|
<Headline>Headline Semi Bold</Headline>
|
||||||
<Title>Title</Title>
|
<Title>Title</Title>
|
|
@ -14,12 +14,22 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { forwardRef } from "react";
|
import { createElement, forwardRef, ReactNode } from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Link as RouterLink } from "react-router-dom";
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
|
import * as H from "history";
|
||||||
|
|
||||||
import styles from "./Typography.module.css";
|
import styles from "./Typography.module.css";
|
||||||
|
|
||||||
export const Headline = forwardRef(
|
interface TypographyProps {
|
||||||
|
children: ReactNode;
|
||||||
|
fontWeight?: string;
|
||||||
|
className?: string;
|
||||||
|
overflowEllipsis?: boolean;
|
||||||
|
as?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Headline = forwardRef<HTMLHeadingElement, TypographyProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
as: Component = "h1",
|
as: Component = "h1",
|
||||||
|
@ -31,23 +41,23 @@ export const Headline = forwardRef(
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return createElement(
|
||||||
<Component
|
Component,
|
||||||
{...rest}
|
{
|
||||||
className={classNames(
|
...rest,
|
||||||
|
className: classNames(
|
||||||
styles[fontWeight],
|
styles[fontWeight],
|
||||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||||
className
|
className
|
||||||
)}
|
),
|
||||||
ref={ref}
|
ref,
|
||||||
>
|
},
|
||||||
{children}
|
children
|
||||||
</Component>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Title = forwardRef(
|
export const Title = forwardRef<HTMLHeadingElement, TypographyProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
as: Component = "h2",
|
as: Component = "h2",
|
||||||
|
@ -59,23 +69,23 @@ export const Title = forwardRef(
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return createElement(
|
||||||
<Component
|
Component,
|
||||||
{...rest}
|
{
|
||||||
className={classNames(
|
...rest,
|
||||||
|
className: classNames(
|
||||||
styles[fontWeight],
|
styles[fontWeight],
|
||||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||||
className
|
className
|
||||||
)}
|
),
|
||||||
ref={ref}
|
ref,
|
||||||
>
|
},
|
||||||
{children}
|
children
|
||||||
</Component>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Subtitle = forwardRef(
|
export const Subtitle = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
as: Component = "h3",
|
as: Component = "h3",
|
||||||
|
@ -87,23 +97,23 @@ export const Subtitle = forwardRef(
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return createElement(
|
||||||
<Component
|
Component,
|
||||||
{...rest}
|
{
|
||||||
className={classNames(
|
...rest,
|
||||||
|
className: classNames(
|
||||||
styles[fontWeight],
|
styles[fontWeight],
|
||||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||||
className
|
className
|
||||||
)}
|
),
|
||||||
ref={ref}
|
ref,
|
||||||
>
|
},
|
||||||
{children}
|
children
|
||||||
</Component>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Body = forwardRef(
|
export const Body = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
as: Component = "p",
|
as: Component = "p",
|
||||||
|
@ -115,23 +125,23 @@ export const Body = forwardRef(
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return createElement(
|
||||||
<Component
|
Component,
|
||||||
{...rest}
|
{
|
||||||
className={classNames(
|
...rest,
|
||||||
|
className: classNames(
|
||||||
styles[fontWeight],
|
styles[fontWeight],
|
||||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||||
className
|
className
|
||||||
)}
|
),
|
||||||
ref={ref}
|
ref,
|
||||||
>
|
},
|
||||||
{children}
|
children
|
||||||
</Component>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Caption = forwardRef(
|
export const Caption = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
as: Component = "p",
|
as: Component = "p",
|
||||||
|
@ -143,24 +153,24 @@ export const Caption = forwardRef(
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return createElement(
|
||||||
<Component
|
Component,
|
||||||
{...rest}
|
{
|
||||||
className={classNames(
|
...rest,
|
||||||
|
className: classNames(
|
||||||
styles.caption,
|
styles.caption,
|
||||||
styles[fontWeight],
|
styles[fontWeight],
|
||||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||||
className
|
className
|
||||||
)}
|
),
|
||||||
ref={ref}
|
ref,
|
||||||
>
|
},
|
||||||
{children}
|
children
|
||||||
</Component>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Micro = forwardRef(
|
export const Micro = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
as: Component = "p",
|
as: Component = "p",
|
||||||
|
@ -172,24 +182,29 @@ export const Micro = forwardRef(
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return createElement(
|
||||||
<Component
|
Component,
|
||||||
{...rest}
|
{
|
||||||
className={classNames(
|
...rest,
|
||||||
|
className: classNames(
|
||||||
styles.micro,
|
styles.micro,
|
||||||
styles[fontWeight],
|
styles[fontWeight],
|
||||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||||
className
|
className
|
||||||
)}
|
),
|
||||||
ref={ref}
|
ref,
|
||||||
>
|
},
|
||||||
{children}
|
children
|
||||||
</Component>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Link = forwardRef(
|
interface LinkProps extends TypographyProps {
|
||||||
|
to?: H.LocationDescriptor<unknown>;
|
||||||
|
color?: string;
|
||||||
|
href?: string;
|
||||||
|
}
|
||||||
|
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
as,
|
as,
|
||||||
|
@ -204,8 +219,8 @@ export const Link = forwardRef(
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const Component = as || (to ? RouterLink : "a");
|
const Component: string | RouterLink = as || (to ? RouterLink : "a");
|
||||||
let externalLinkProps;
|
let externalLinkProps: { href: string; target: string; rel: string };
|
||||||
|
|
||||||
if (href) {
|
if (href) {
|
||||||
externalLinkProps = {
|
externalLinkProps = {
|
||||||
|
@ -215,21 +230,21 @@ export const Link = forwardRef(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return createElement(
|
||||||
<Component
|
Component,
|
||||||
{...externalLinkProps}
|
{
|
||||||
{...rest}
|
...externalLinkProps,
|
||||||
to={to}
|
...rest,
|
||||||
className={classNames(
|
to: to,
|
||||||
|
className: classNames(
|
||||||
styles[color],
|
styles[color],
|
||||||
styles[fontWeight],
|
styles[fontWeight],
|
||||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||||
className
|
className
|
||||||
)}
|
),
|
||||||
ref={ref}
|
ref: ref,
|
||||||
>
|
},
|
||||||
{children}
|
children
|
||||||
</Component>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
Loading…
Reference in a new issue