Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding the ability to disable modals for TagSet component #5753

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ export default {
containerWidth: {
control: { type: 'range', min: 20, max: 800, step: 10 },
},
disableOverflowPopup: {
control: { type: 'boolean' },
description:
'Disable the overflow tags popup component, default to false.',
},
allTagsModalTargetCustomDomNode: {
control: { type: 'boolean' },
description: 'Optional DOM node: Modal target defaults to document.body',
Expand Down Expand Up @@ -167,6 +172,7 @@ const Template = (argsIn) => {
<div style={{ width: containerWidth }} ref={ref}>
<TagSet
{...args}
disableOverflowPopup={args.disableOverflowPopup}
allTagsModalTarget={
allTagsModalTargetCustomDomNode ? ref.current : undefined
}
Expand Down
24 changes: 23 additions & 1 deletion packages/ibm-products/src/components/TagSet/TagSet.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ describe(TagSet.displayName, () => {
const visibleTags = 5;
window.innerWidth = tagWidth * (visibleTags + 1) + 1; // + 1 for overflow

// const { container } =
render(<TagSet {...overflowAndModalStrings} tags={tags} />);

const overflow = screen.getByText(`+${tags.length - visibleTags}`);
Expand All @@ -197,6 +196,29 @@ describe(TagSet.displayName, () => {
expect(modal).not.toHaveClass('is-visible');
});

it('Tag overflow can be disabled, and clicking on the overflow does not show TagSetModal or overflow popup', async () => {
const visibleTags = 5;
window.innerWidth = tagWidth * (visibleTags + 1) + 1; // + 1 for overflow

const { queryByText } = render(
<TagSet
{...overflowAndModalStrings}
disableOverflowPopup={true}
tags={tags}
/>
);

// Ensure the number of visible elements are rendered on the screen
expect(queryByText(`+${tags.length - visibleTags}`)).toBeInTheDocument();

// Ensure the overflow popup is not rendered onto the screen
expect(queryByText('View all tags')).toBeNull();

// Ensure the modal is not rendered onto the screen
const modal = screen.queryByRole('presentation');
expect(modal).not.toBeInTheDocument();
});

it('it requires strings for overflow and modal when more than ten tags supplied.', async () =>
expectMultipleError(
[
Expand Down
31 changes: 22 additions & 9 deletions packages/ibm-products/src/components/TagSet/TagSet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ interface TagSetProps extends PropsWithChildren {
* Default will measure the available space of the TagSet container itself.
*/
containingElementRef?: React.RefObject<HTMLElement>;
/**
* Disable the overflow tags popup component, default to false.
*/
disableOverflowPopup?: boolean;
/**
* maximum visible tags
*/
Expand Down Expand Up @@ -161,6 +165,7 @@ export let TagSet = React.forwardRef<HTMLDivElement, TagSetProps>(
allTagsModalSearchLabel,
allTagsModalSearchPlaceholderText,
showAllTagsLabel,
disableOverflowPopup = false,
jeesonjohnson marked this conversation as resolved.
Show resolved Hide resolved
tags,
containingElementRef,
measurementOffset = defaults.measurementOffset,
Expand Down Expand Up @@ -268,6 +273,7 @@ export let TagSet = React.forwardRef<HTMLDivElement, TagSetProps>(
key="displayed-tag-overflow"
ref={overflowTag}
popoverOpen={popoverOpen}
disablePopOver={disableOverflowPopup}
setPopoverOpen={setPopoverOpen}
/>
);
Expand All @@ -280,6 +286,7 @@ export let TagSet = React.forwardRef<HTMLDivElement, TagSetProps>(
overflowClassName,
overflowType,
showAllTagsLabel,
disableOverflowPopup,
tags,
onOverflowTagChange,
popoverOpen,
Expand Down Expand Up @@ -399,15 +406,17 @@ export let TagSet = React.forwardRef<HTMLDivElement, TagSetProps>(
{displayedTags}
</div>
</div>
<TagSetModal
allTags={tags}
open={showAllModalOpen}
title={allTagsModalTitle}
onClose={handleModalClose}
searchLabel={allTagsModalSearchLabel}
searchPlaceholder={allTagsModalSearchPlaceholderText}
portalTarget={allTagsModalTarget}
/>
{!disableOverflowPopup && (
<TagSetModal
allTags={tags}
open={showAllModalOpen}
title={allTagsModalTitle}
onClose={handleModalClose}
searchLabel={allTagsModalSearchLabel}
searchPlaceholder={allTagsModalSearchPlaceholderText}
portalTarget={allTagsModalTarget}
/>
)}
</div>
);
}
Expand Down Expand Up @@ -475,6 +484,10 @@ TagSet.propTypes = {
*/
/**@ts-ignore */
containingElementRef: PropTypes.object,
/**
* Disable the overflow tags popup component, default to false.
*/
disableOverflowPopup: PropTypes.bool,
/**
* maximum visible tags
*/
Expand Down
27 changes: 27 additions & 0 deletions packages/ibm-products/src/components/TagSet/TagSetOverflow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ interface TagSetOverflowProps {
* className
*/
className?: string;
/**
* Disable the popover component from being rendered. Defaults to false.
*/
disablePopOver?: boolean;
/**
* function to execute on clicking show all
*/
Expand Down Expand Up @@ -87,6 +91,7 @@ export const TagSetOverflow = React.forwardRef(
// The component props, in alphabetical order (for consistency).

allTagsModalSearchThreshold = defaults.allTagsModalSearchThreshold,
disablePopOver = false,
jeesonjohnson marked this conversation as resolved.
Show resolved Hide resolved
className,
onShowAllClick,
overflowAlign = 'bottom',
Expand Down Expand Up @@ -123,6 +128,24 @@ export const TagSetOverflow = React.forwardRef(
}
};

if (disablePopOver) {
return (
<span
{
// Pass through any other property values as HTML attributes.
...rest
}
aria-hidden={overflowTags.length === 0}
className={cx(`${blockClass}`, {
[`${blockClass}--hidden`]: overflowTags.length === 0,
})}
ref={ref || localRef}
>
<Tag>+{overflowTags.length}</Tag>
</span>
);
}

return (
<span
{
Expand Down Expand Up @@ -213,6 +236,10 @@ TagSetOverflow.propTypes = {
* className
*/
className: PropTypes.string,
/**
* Disable the popover component from being rendered. Defaults to false.
*/
disablePopOver: PropTypes.bool,
/**
* function to execute on clicking show all
*/
Expand Down
Loading