80 lines
1.7 KiB
TypeScript
80 lines
1.7 KiB
TypeScript
import {
|
|
Component,
|
|
createEffect,
|
|
splitProps,
|
|
type JSX,
|
|
type ParentComponent,
|
|
} from "solid-js";
|
|
import { css } from "solid-styled";
|
|
import { useTabListContext } from "./Tabs";
|
|
|
|
const Tab: ParentComponent<
|
|
{
|
|
focus?: boolean;
|
|
large?: boolean;
|
|
} & JSX.ButtonHTMLAttributes<HTMLButtonElement>
|
|
> = (props) => {
|
|
const [managed, rest] = splitProps(props, [
|
|
"focus",
|
|
"large",
|
|
"type",
|
|
"role",
|
|
"ref",
|
|
]);
|
|
let self: HTMLButtonElement;
|
|
const {
|
|
focusOn: [, setFocusOn],
|
|
} = useTabListContext();
|
|
|
|
createEffect<boolean | undefined>((lastStatus) => {
|
|
if (managed.focus && !lastStatus) {
|
|
setFocusOn((x) => [...x, self]);
|
|
}
|
|
if (!managed.focus && lastStatus) {
|
|
setFocusOn((x) => x.filter((e) => e !== self));
|
|
}
|
|
return managed.focus;
|
|
});
|
|
css`
|
|
.tab {
|
|
cursor: pointer;
|
|
background: none;
|
|
border: none;
|
|
min-width: ${managed.large ? "160px" : "72px"};
|
|
height: 48px;
|
|
max-width: min(calc(100% - 56px), 264px);
|
|
padding: 10px 24px;
|
|
font-size: 0.8135rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
transition: color 120ms var(--tutu-anim-curve-std);
|
|
}
|
|
|
|
:global(.MuiToolbar-root) .tab {
|
|
color: rgba(255, 255, 255, 0.7);
|
|
|
|
&:hover,
|
|
&:focus,
|
|
&.focus,
|
|
&:global(.tablist-focus) {
|
|
color: white;
|
|
}
|
|
}
|
|
`;
|
|
return (
|
|
<button
|
|
ref={(x) => {
|
|
self = x;
|
|
(managed.ref as (e: HTMLButtonElement) => void)?.(x);
|
|
}}
|
|
type={managed.type ?? "button"}
|
|
classList={{ tab: true, focus: managed.focus }}
|
|
role={managed.role ?? "tab"}
|
|
{...rest}
|
|
>
|
|
{props.children}
|
|
</button>
|
|
);
|
|
};
|
|
|
|
export default Tab;
|