Skip to content

Commit

Permalink
fix(theme): add truncate class to the list item to avoid overflow the…
Browse files Browse the repository at this point in the history
… wrapper (#4105)

* fix(docs): invalid canary storybook link (#4030)

* fix: menu item hidden overflow text

* feat: changeset

* Merge branch 'beta/release-next' into fix/menu-item-hidden

* fix: truncate list item

* feat: update changeset

* fix(menu): omit internal props

---------

Co-authored-by: աӄա <wingkwong.code@gmail.com>
Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
  • Loading branch information
3 people authored Nov 27, 2024
1 parent 4598638 commit 256d462
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .changeset/lazy-buttons-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@nextui-org/listbox": patch
"@nextui-org/menu": patch
"@nextui-org/theme": patch
---

Add truncate class to the list item to avoid overflow the wrapper
26 changes: 26 additions & 0 deletions packages/components/listbox/__tests__/listbox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,30 @@ describe("Listbox", () => {

expect(checkmark1).toBeFalsy();
});

it("should truncate the text if the child is not a string", () => {
const wrapper = render(
<Listbox>
<ListboxItem key="new">New file</ListboxItem>
</Listbox>,
);

const menuItem = wrapper.getByText("New file");

expect(menuItem).toHaveProperty("className", expect.stringContaining("truncate"));
});

it("should not truncate the text if the child is a string", () => {
const wrapper = render(
<Listbox>
<ListboxItem key="new">
<div>New file</div>
</ListboxItem>
</Listbox>,
);

const menuItem = wrapper.getByText("New file").parentElement;

expect(menuItem).not.toHaveProperty("className", expect.stringContaining("truncate"));
});
});
4 changes: 3 additions & 1 deletion packages/components/listbox/src/use-listbox-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ export function useListboxItem<T extends object>(originalProps: UseListboxItemPr
...variantProps,
isDisabled,
disableAnimation,
hasTitleTextChild: typeof rendered === "string",
hasDescriptionTextChild: typeof description === "string",
}),
[objectToDeps(variantProps), isDisabled, disableAnimation],
[objectToDeps(variantProps), isDisabled, disableAnimation, rendered, description],
);

const baseStyles = clsx(classNames?.base, className);
Expand Down
26 changes: 26 additions & 0 deletions packages/components/menu/__tests__/menu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,30 @@ describe("Menu", () => {
expect(onPress).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledTimes(1);
});

it("should truncate the text if the child is not a string", () => {
const wrapper = render(
<Menu>
<MenuItem key="new">New file</MenuItem>
</Menu>,
);

const menuItem = wrapper.getByText("New file");

expect(menuItem).toHaveProperty("className", expect.stringContaining("truncate"));
});

it("should not truncate the text if the child is a string", () => {
const wrapper = render(
<Menu>
<MenuItem key="new">
<div>New file</div>
</MenuItem>
</Menu>,
);

const menuItem = wrapper.getByText("New file").parentElement;

expect(menuItem).not.toHaveProperty("className", expect.stringContaining("truncate"));
});
});
5 changes: 4 additions & 1 deletion packages/components/menu/src/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ function Menu<T extends object>(props: Props<T>, ref: ForwardedRef<HTMLUListElem
);
}

export type MenuProps<T extends object = object> = Props<T> & {ref?: Ref<HTMLElement>};
export type MenuProps<T extends object = object> = Omit<
Props<T>,
"hasChildItems" | "hasTitleTextChild" | "hasDescriptionTextChild"
> & {ref?: Ref<HTMLElement>};

// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(Menu) as <T extends object>(props: MenuProps<T>) => ReactElement;
Expand Down
4 changes: 3 additions & 1 deletion packages/components/menu/src/use-menu-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,10 @@ export function useMenuItem<T extends object>(originalProps: UseMenuItemProps<T>
...variantProps,
isDisabled,
disableAnimation,
hasTitleTextChild: typeof rendered === "string",
hasDescriptionTextChild: typeof description === "string",
}),
[objectToDeps(variantProps), isDisabled, disableAnimation],
[objectToDeps(variantProps), isDisabled, disableAnimation, rendered, description],
);

const baseStyles = clsx(classNames?.base, className);
Expand Down
13 changes: 12 additions & 1 deletion packages/core/theme/src/components/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {dataFocusVisibleClasses} from "../utils";
*/
const menu = tv({
slots: {
base: "w-full relative flex flex-col gap-1 p-1",
base: "w-full relative flex flex-col gap-1 p-1 overflow-hidden",
list: "w-full flex flex-col gap-0.5 outline-none",
emptyContent: [
"h-10",
Expand Down Expand Up @@ -144,6 +144,17 @@ const menuItem = tv({
base: "data-[hover=true]:transition-colors",
},
},
// If the child isn't a string, the truncate such as `overflow, white-space, text-overflow` css won't be extended to the child, so we remove the truncate class here
hasTitleTextChild: {
true: {
title: "truncate",
},
},
hasDescriptionTextChild: {
true: {
description: "truncate",
},
},
},
defaultVariants: {
variant: "solid",
Expand Down

0 comments on commit 256d462

Please sign in to comment.