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 { TabContainer, TabItem } from "./Tabs";
|
||||
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
|
||||
import { ReactComponent as VideoIcon } from "../icons/Video.svg";
|
||||
|
@ -29,7 +30,7 @@ export default {
|
|||
},
|
||||
};
|
||||
|
||||
export const Tabs = () => (
|
||||
export const Tabs: React.FC<{}> = () => (
|
||||
<TabContainer>
|
||||
<TabItem
|
||||
title={
|
|
@ -17,19 +17,28 @@ limitations under the License.
|
|||
import React, { useRef } from "react";
|
||||
import { useTabList, useTab, useTabPanel } from "@react-aria/tabs";
|
||||
import { Item } from "@react-stately/collections";
|
||||
import { useTabListState } from "@react-stately/tabs";
|
||||
import styles from "./Tabs.module.css";
|
||||
import { useTabListState, TabListState } from "@react-stately/tabs";
|
||||
import classNames from "classnames";
|
||||
import { AriaTabPanelProps, TabListProps } from "@react-types/tabs";
|
||||
import { Node } from "@react-types/shared";
|
||||
|
||||
export function TabContainer(props) {
|
||||
const state = useTabListState(props);
|
||||
const ref = useRef();
|
||||
import styles from "./Tabs.module.css";
|
||||
|
||||
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);
|
||||
return (
|
||||
<div className={classNames(styles.tabContainer, props.className)}>
|
||||
<ul {...tabListProps} ref={ref} className={styles.tabList}>
|
||||
{[...state.collection].map((item) => (
|
||||
<Tab key={item.key} item={item} state={state} />
|
||||
<Tab item={item} state={state} />
|
||||
))}
|
||||
</ul>
|
||||
<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 ref = useRef();
|
||||
const ref = useRef<HTMLLIElement>();
|
||||
const { tabProps } = useTab({ key }, state, ref);
|
||||
|
||||
return (
|
||||
|
@ -56,8 +70,12 @@ function Tab({ item, state }) {
|
|||
);
|
||||
}
|
||||
|
||||
function TabPanel({ state, ...props }) {
|
||||
const ref = useRef();
|
||||
interface TabPanelProps<T> extends AriaTabPanelProps {
|
||||
state: TabListState<T>;
|
||||
}
|
||||
|
||||
function TabPanel<T>({ state, ...props }: TabPanelProps<T>): JSX.Element {
|
||||
const ref = useRef<HTMLDivElement>();
|
||||
const { tabPanelProps } = useTabPanel(props, state, ref);
|
||||
return (
|
||||
<div {...tabPanelProps} ref={ref} className={styles.tabPanel}>
|
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { Headline, Title, Subtitle, Body, Caption, Micro } from "./Typography";
|
||||
|
||||
export default {
|
||||
|
@ -24,7 +25,7 @@ export default {
|
|||
},
|
||||
};
|
||||
|
||||
export const Typography = () => (
|
||||
export const Typography: React.FC<{}> = () => (
|
||||
<>
|
||||
<Headline>Headline Semi Bold</Headline>
|
||||
<Title>Title</Title>
|
|
@ -14,12 +14,22 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { forwardRef } from "react";
|
||||
import { createElement, forwardRef, ReactNode } from "react";
|
||||
import classNames from "classnames";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import * as H from "history";
|
||||
|
||||
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",
|
||||
|
@ -31,23 +41,23 @@ export const Headline = forwardRef(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
className={classNames(
|
||||
return createElement(
|
||||
Component,
|
||||
{
|
||||
...rest,
|
||||
className: classNames(
|
||||
styles[fontWeight],
|
||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
),
|
||||
ref,
|
||||
},
|
||||
children
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const Title = forwardRef(
|
||||
export const Title = forwardRef<HTMLHeadingElement, TypographyProps>(
|
||||
(
|
||||
{
|
||||
as: Component = "h2",
|
||||
|
@ -59,23 +69,23 @@ export const Title = forwardRef(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
className={classNames(
|
||||
return createElement(
|
||||
Component,
|
||||
{
|
||||
...rest,
|
||||
className: classNames(
|
||||
styles[fontWeight],
|
||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
),
|
||||
ref,
|
||||
},
|
||||
children
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const Subtitle = forwardRef(
|
||||
export const Subtitle = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||
(
|
||||
{
|
||||
as: Component = "h3",
|
||||
|
@ -87,23 +97,23 @@ export const Subtitle = forwardRef(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
className={classNames(
|
||||
return createElement(
|
||||
Component,
|
||||
{
|
||||
...rest,
|
||||
className: classNames(
|
||||
styles[fontWeight],
|
||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
),
|
||||
ref,
|
||||
},
|
||||
children
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const Body = forwardRef(
|
||||
export const Body = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||
(
|
||||
{
|
||||
as: Component = "p",
|
||||
|
@ -115,23 +125,23 @@ export const Body = forwardRef(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
className={classNames(
|
||||
return createElement(
|
||||
Component,
|
||||
{
|
||||
...rest,
|
||||
className: classNames(
|
||||
styles[fontWeight],
|
||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
),
|
||||
ref,
|
||||
},
|
||||
children
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const Caption = forwardRef(
|
||||
export const Caption = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||
(
|
||||
{
|
||||
as: Component = "p",
|
||||
|
@ -143,24 +153,24 @@ export const Caption = forwardRef(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
className={classNames(
|
||||
return createElement(
|
||||
Component,
|
||||
{
|
||||
...rest,
|
||||
className: classNames(
|
||||
styles.caption,
|
||||
styles[fontWeight],
|
||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
),
|
||||
ref,
|
||||
},
|
||||
children
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const Micro = forwardRef(
|
||||
export const Micro = forwardRef<HTMLParagraphElement, TypographyProps>(
|
||||
(
|
||||
{
|
||||
as: Component = "p",
|
||||
|
@ -172,24 +182,29 @@ export const Micro = forwardRef(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
className={classNames(
|
||||
return createElement(
|
||||
Component,
|
||||
{
|
||||
...rest,
|
||||
className: classNames(
|
||||
styles.micro,
|
||||
styles[fontWeight],
|
||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
),
|
||||
ref,
|
||||
},
|
||||
children
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const Link = forwardRef(
|
||||
interface LinkProps extends TypographyProps {
|
||||
to?: H.LocationDescriptor<unknown>;
|
||||
color?: string;
|
||||
href?: string;
|
||||
}
|
||||
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
||||
(
|
||||
{
|
||||
as,
|
||||
|
@ -204,8 +219,8 @@ export const Link = forwardRef(
|
|||
},
|
||||
ref
|
||||
) => {
|
||||
const Component = as || (to ? RouterLink : "a");
|
||||
let externalLinkProps;
|
||||
const Component: string | RouterLink = as || (to ? RouterLink : "a");
|
||||
let externalLinkProps: { href: string; target: string; rel: string };
|
||||
|
||||
if (href) {
|
||||
externalLinkProps = {
|
||||
|
@ -215,21 +230,21 @@ export const Link = forwardRef(
|
|||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...externalLinkProps}
|
||||
{...rest}
|
||||
to={to}
|
||||
className={classNames(
|
||||
return createElement(
|
||||
Component,
|
||||
{
|
||||
...externalLinkProps,
|
||||
...rest,
|
||||
to: to,
|
||||
className: classNames(
|
||||
styles[color],
|
||||
styles[fontWeight],
|
||||
{ [styles.overflowEllipsis]: overflowEllipsis },
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
),
|
||||
ref: ref,
|
||||
},
|
||||
children
|
||||
);
|
||||
}
|
||||
);
|
Loading…
Reference in a new issue