Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding committed Aug 22, 2024
1 parent 32e88c4 commit 806921e
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 127 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { StackLayout } from "@salt-ds/core";
import * as tabstripStories from "@stories/tabstrip-next/tabstrip-next.stories";
import { composeStories } from "@storybook/react";
import { DefaultLeftAligned } from "@stories/tabstrip-next/tabstrip-next.stories";

const { DefaultLeftAligned: DefaultTabstrip, ControlledTabstrip } =
const { DefaultLeftAligned: DefaultTabstrip, LotsOfTabsTabstrip } =
composeStories(tabstripStories);

describe("Given a Tabstrip", () => {
Expand Down Expand Up @@ -76,11 +77,11 @@ describe("Given a Tabstrip", () => {
});
describe("WHEN size is not the full width of it's parent", () => {
it("THEN should not overflow if it has enough space", () => {
cy.mount(<ControlledTabstrip width={550} />);
cy.mount(<DefaultLeftAligned />);
cy.findByRole("tab", { name: /more tabs/ }).should("not.exist");
});
it("THEN should overflow if it there is not enough space", () => {
cy.mount(<ControlledTabstrip width={450} />);
cy.mount(<LotsOfTabsTabstrip />);
cy.findByRole("tab", { name: /more tabs/ }).should("exist");
});
});
Expand Down
4 changes: 3 additions & 1 deletion packages/lab/src/tabs-next/TabNext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ export const TabNext = forwardRef<HTMLDivElement, TabNextProps>(
};

useEffect(() => {
return registerItem({ id: value, element: tabRef.current });
if (value && tabRef.current) {
return registerItem({ id: value, element: tabRef.current });
}
}, [value]);

const closeButtonId = useId();
Expand Down
4 changes: 4 additions & 0 deletions packages/lab/src/tabs-next/TabOverflowList.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
justify-content: start;
}

.saltTabOverflow-list [role="tab"] .saltTabNext-label {
justify-content: start;
}

.saltTabOverflow-list [role="tab"]::after {
display: none;
}
Expand Down
90 changes: 51 additions & 39 deletions packages/lab/src/tabs-next/TabOverflowList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,72 @@ import {
Children,
type ComponentPropsWithoutRef,
type ReactNode,
type Ref,
forwardRef,
useState,
} from "react";
import tabOverflowListCss from "./TabOverflowList.css";

interface TabOverflowListProps extends ComponentPropsWithoutRef<"button"> {
buttonRef?: Ref<HTMLButtonElement>;
children?: ReactNode;
isMeasuring?: boolean;
}

const withBaseName = makePrefixer("saltTabOverflow");

export function TabOverflowList(props: TabOverflowListProps) {
const { children, ...rest } = props;
const [hidden, setHidden] = useState(true);
export const TabOverflowList = forwardRef<HTMLDivElement, TabOverflowListProps>(
function TabOverflowList(props, ref) {
const { buttonRef, children, isMeasuring, ...rest } = props;
const [hidden, setHidden] = useState(true);

const targetWindow = useWindow();
useComponentCssInjection({
testId: "salt-tabstrip-next-overflow",
css: tabOverflowListCss,
window: targetWindow,
});
const targetWindow = useWindow();
useComponentCssInjection({
testId: "salt-tabstrip-next-overflow",
css: tabOverflowListCss,
window: targetWindow,
});

const handleClick = () => {
setHidden((old) => !old);
};
const handleClick = () => {
setHidden((old) => !old);
};

const handleFocus = () => {
setHidden(false);
};
const handleFocus = () => {
setHidden(false);
};

const handleBlur = () => {
setHidden(true);
};
const handleBlur = () => {
setHidden(true);
};

const handleListClick = () => {
setHidden(true);
};
const handleListClick = () => {
setHidden(true);
};

if (Children.count(children) === 0) return null;
if (Children.count(children) === 0 && !isMeasuring) return null;

return (
<div className={withBaseName()}>
<Button tabIndex={-1} variant="secondary" onClick={handleClick} {...rest}>
<OverflowMenuIcon aria-hidden />
</Button>
{/* biome-ignore lint/a11y/useKeyWithClickEvents: <explanation> */}
<div
className={withBaseName("list")}
data-hidden={hidden}
onFocus={handleFocus}
onBlur={handleBlur}
onClick={handleListClick}
>
<div className={withBaseName("listContainer")}>{children}</div>
return (
<div className={withBaseName()} ref={ref}>
<Button
tabIndex={-1}
variant="secondary"
onClick={handleClick}
ref={buttonRef}
{...rest}
>
<OverflowMenuIcon aria-hidden />
</Button>
{/* biome-ignore lint/a11y/useKeyWithClickEvents: <explanation> */}
<div
className={withBaseName("list")}
data-hidden={hidden}
onFocus={handleFocus}
onBlur={handleBlur}
onClick={handleListClick}
>
<div className={withBaseName("listContainer")}>{children}</div>
</div>
</div>
</div>
);
}
);
},
);
31 changes: 24 additions & 7 deletions packages/lab/src/tabs-next/TabstripNext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,22 @@ export const TabstripNext = forwardRef<HTMLDivElement, TabstripNextProps>(

const tabstripRef = useRef<HTMLDivElement>(null);
const handleRef = useForkRef(tabstripRef, ref);
const { registerItem, setSelected, selected, handleKeyDown } = useTabstrip({
defaultSelected: defaultValue,
selected: value,
});
const addButtonRef = useRef<HTMLButtonElement>(null);
const overflowButtonRef = useRef<HTMLButtonElement>(null);

const { registerItem, setSelected, selected, handleKeyDown, items } =
useTabstrip({
defaultSelected: defaultValue,
selected: value,
});

const [visible, hidden] = useOverflow({
const [visible, hidden, isMeasuring] = useOverflow({
container: tabstripRef,
tabs: items,
children,
selected,
addButton: addButtonRef,
overflowButton: overflowButtonRef,
});

const [focusInside, setFocusInside] = useState(false);
Expand Down Expand Up @@ -119,11 +126,21 @@ export const TabstripNext = forwardRef<HTMLDivElement, TabstripNextProps>(
>
{visible}
{onAdd && (
<Button aria-label="Add Tab" variant="secondary" onClick={onAdd}>
<Button
ref={addButtonRef}
aria-label="Add Tab"
variant="secondary"
onClick={onAdd}
>
<AddIcon aria-hidden />
</Button>
)}
<TabOverflowList>{hidden}</TabOverflowList>
<TabOverflowList
isMeasuring={isMeasuring}
buttonRef={overflowButtonRef}
>
{hidden}
</TabOverflowList>
</div>
</TabsContext.Provider>
);
Expand Down
Loading

0 comments on commit 806921e

Please sign in to comment.