Skip to content

Commit

Permalink
Merge branch 'main' into fix/datagrid-selectable-row-count-exclude-di…
Browse files Browse the repository at this point in the history
…sabled
  • Loading branch information
sangeethababu9223 committed Sep 20, 2024
2 parents ae74e83 + 03eadd2 commit 64602a2
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 17 deletions.
67 changes: 67 additions & 0 deletions e2e/components/AboutModal/AboutModal-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,71 @@ test.describe('AboutModal @avt', () => {

await expect(closeButton).toBeFocused();
});

test('@avt-open-close-with-focus-trap', async ({ page }) => {
await visitStory(page, {
component: 'AboutModal',
id: 'ibm-products-components-about-modal-aboutmodal--about-modal-with-all-props-set',
globals: {
carbonTheme: 'white',
},
});

const modalElement = page.locator(`.${carbon.prefix}--modal`);
const openButton = page.getByText(
'Open the About modal with all props set'
);
const closeIcon = page.getByLabel('Close');
const linkActions = page.getByText('Link action');

// Focus the open button
await page.keyboard.press('Tab');
// Expect open button to be focused
await expect(openButton).toBeFocused();
// Open modal by pressing 'Enter' key
await page.keyboard.press('Enter');

// Opening modal
await modalElement.evaluate((element) =>
Promise.all(
element.getAnimations().map((animation) => animation.finished)
)
);

await expect(page).toHaveNoACViolations(
'AboutModal @avt-open-close-with-focus-trap'
);

// Initial focus should be on close button
await expect(closeIcon).toBeFocused();
// Press tab to move focus to first link element
await page.keyboard.press('Tab');
await expect(linkActions.first()).toBeFocused();

// Press tab to move focus to second link element
await page.keyboard.press('Tab');
await expect(linkActions.nth(1)).toBeFocused();

// Press tab to move focus to last link element
await page.keyboard.press('Tab');
await expect(linkActions.last()).toBeFocused();

// Press tab to move focus back to close button
await page.keyboard.press('Tab');
await expect(closeIcon).toBeFocused();

// Press escape to twise
// first to close tooltip then close modal
await page.keyboard.press('Escape');
await page.keyboard.press('Escape');

// Opening modal
await modalElement.evaluate((element) =>
Promise.all(
element.getAnimations().map((animation) => animation.finished)
)
);

await expect(modalElement).toHaveAttribute('aria-hidden', 'true');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3207,6 +3207,8 @@ p.c4p--about-modal__copyright-text:first-child {
}
.c4p--tearsheet.c4p--tearsheet--has-slug:not(.c4p--tearsheet--has-close) .cds--slug {
inset-inline-end: 0;
margin-block: 6px;
margin-inline-end: 1rem;
}
.c4p--create-tearsheet-narrow .cds--modal-header__heading,
Expand Down Expand Up @@ -3982,6 +3984,10 @@ p.c4p--about-modal__copyright-text:first-child {
padding: 0;
}
.c4p--datagrid .cds--noLabel svg.cds--btn__icon {
margin-inline-start: 0;
}
.c4p--datagrid .cds--action-list .cds--btn__icon {
margin-top: 0;
}
Expand Down Expand Up @@ -4213,6 +4219,7 @@ p.c4p--about-modal__copyright-text:first-child {
}
.c4p--datagrid__sortableColumn .cds--table-sort.c4p--datagrid--table-sort {
width: calc(100% + 2rem);
align-items: inherit;
margin: 0 calc(-1 * 1rem);
}
Expand Down Expand Up @@ -8875,6 +8882,7 @@ button.c4p--add-select__global-filter-toggle--open {
}
.c4p--tag-set-overflow__tagset-popover .c4p--tag-set-overflow__popover-trigger {
font-family: inherit;
border: none !important;
}
.c4p--tag-set-overflow__tagset-popover .c4p--tag-set-overflow__show-all-tags-link.cds--link:visited {
display: inline-block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ $block-class-modal: #{$_block-class}-modal;
}

.#{$block-class-overflow}__popover-trigger {
/* stylelint-disable-next-line declaration-no-important */
border: none !important;
font-family: inherit;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ createFullPageWithHeader.args = {
{ key: '3', label: 'Breadcrumb 4', isCurrentPage: true },
],
maxVisibleBreadcrumbs: 3,
breadcrumbOverflowTooltipAlign: 'right',
};

export const createFullPageWithStepInErrorState = TemplateWithError.bind({});
Expand Down Expand Up @@ -818,4 +819,5 @@ createFullPageWithGlobalHeader.args = {
{ key: '3', label: 'Breadcrumb 4', isCurrentPage: true },
],
maxVisibleBreadcrumbs: 3,
breadcrumbOverflowTooltipAlign: 'right',
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ModalBody,
ModalFooter,
ModalHeader,
Tooltip,
} from '@carbon/react';
// Import portions of React that are needed.
import React, {
Expand Down Expand Up @@ -79,6 +80,8 @@ type CreateFullPageBreadcrumbsProps =
* Label for open/close overflow button used for breadcrumb items that do not fit
*/
breadcrumbsOverflowAriaLabel?: never;

breadcrumbOverflowTooltipAlign?: never;
}
| {
/** The header breadcrumbs */
Expand All @@ -88,6 +91,8 @@ type CreateFullPageBreadcrumbsProps =
* Label for open/close overflow button used for breadcrumb items that do not fit
*/
breadcrumbsOverflowAriaLabel: string;

breadcrumbOverflowTooltipAlign?: string;
};

type CreateFullPageBaseProps = {
Expand Down Expand Up @@ -235,6 +240,7 @@ export let CreateFullPage = React.forwardRef(
noTrailingSlash,
title,
secondaryTitle,
breadcrumbOverflowTooltipAlign = 'right',
...rest
}: CreateFullPageProps,
ref: ForwardedRef<HTMLDivElement>
Expand Down Expand Up @@ -340,6 +346,7 @@ export let CreateFullPage = React.forwardRef(
overflowAriaLabel={breadcrumbsOverflowAriaLabel}
maxVisible={maxVisibleBreadcrumbs}
className={`${blockClass}__header`}
overflowTooltipAlign={breadcrumbOverflowTooltipAlign}
/>
)}
<div className={`${blockClass}__influencer-and-body-container`}>
Expand Down Expand Up @@ -433,6 +440,11 @@ CreateFullPage.propTypes = {
*/
backButtonText: PropTypes.string.isRequired,

/**
* align breadcrumb overflow tooltip
*/
breadcrumbOverflowTooltipAlign: Tooltip.propTypes.align,

/** The header breadcrumbs */
/**@ts-ignore */
breadcrumbs: PropTypes.arrayOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { pkg } from '../../settings';
import pconsole from '../../global/js/utils/pconsole';
import { BreadcrumbWithOverflow } from '../BreadcrumbWithOverflow';
import { isRequiredIf } from '../../global/js/utils/props-helper';
import { Tooltip } from '@carbon/react';

const blockClass = `${pkg.prefix}--simple-header`;
const componentName = 'SimpleHeader';
Expand All @@ -35,6 +36,7 @@ const SimpleHeader = ({
noTrailingSlash = true,
maxVisible,
overflowAriaLabel,
overflowTooltipAlign,
...rest
}) => {
const warnIfNoTitleOrBreadcrumbs = useCallback(() => {
Expand All @@ -58,6 +60,7 @@ const SimpleHeader = ({
breadcrumbs={breadcrumbs}
maxVisible={maxVisible}
overflowAriaLabel={overflowAriaLabel}
overflowTooltipAlign={overflowTooltipAlign}
/>
)}
{title && <h1 className={cx(`${blockClass}__title`)}>{title}</h1>}
Expand Down Expand Up @@ -99,6 +102,10 @@ SimpleHeader.propTypes = {
/** Label for open/close overflow button used for breadcrumb items that do not fit */
overflowAriaLabel: overflowAriaLabel_required_if_breadcrumbs_exist,

/**
* overflowTooltipAlign: align tooltip position
*/
overflowTooltipAlign: Tooltip.propTypes.align,
/** Header title */
title: PropTypes.string,
};
Expand Down
34 changes: 31 additions & 3 deletions packages/ibm-products/src/components/TagSet/TagSet.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// LICENSE file in the root directory of this source tree.
//

import React, { useRef, useState } from 'react';
import React, { useRef, useState, useEffect } from 'react';

import { TYPES as tagTypes } from '../TagSet/constants';
import { pkg } from '../../settings';
Expand Down Expand Up @@ -140,6 +140,15 @@ export default {
containerWidth: {
control: { type: 'range', min: 20, max: 800, step: 10 },
},
size: {
control: {
type: 'select',
},
options: ['sm', 'md', 'lg'],
type: 'string',
description:
'This prop is only for storybook representation, and does not belong to `tagset` component, the size can be passed to each tag{} in tags[], the overflow tag takes the size of last tag{} in tags[]',
},
allTagsModalTargetCustomDomNode: {
control: { type: 'boolean' },
description: 'Optional DOM node: Modal target defaults to document.body',
Expand All @@ -159,9 +168,13 @@ export default {
};

const Template = (argsIn) => {
const { containerWidth, allTagsModalTargetCustomDomNode, ...args } = {
const { containerWidth, allTagsModalTargetCustomDomNode, size, ...args } = {
...argsIn,
};
if (args.tags) {
args.tags = args.tags.map((tag) => ({ ...tag, size }));
}

const ref = useRef();
return (
<div style={{ width: containerWidth }} ref={ref}>
Expand Down Expand Up @@ -204,13 +217,20 @@ HundredsOfTags.args = {
};

const TemplateWithClose = (argsIn) => {
const { containerWidth, allTagsModalTargetCustomDomNode, tags, ...args } = {
const {
containerWidth,
allTagsModalTargetCustomDomNode,
size,
tags,
...args
} = {
...argsIn,
};
const [liveTags, setLiveTags] = useState(
tags.map((tag) => ({
...tag,
filter: true,
size: size,
onClose: () => handleTagClose(tag.label),
}))
);
Expand All @@ -220,6 +240,14 @@ const TemplateWithClose = (argsIn) => {
};

const ref = useRef();
useEffect(() => {
setLiveTags((prevTags) =>
prevTags.map((tag) => ({
...tag,
size: size,
}))
);
}, [size]);
return (
<div style={{ width: containerWidth }} ref={ref}>
<TagSet
Expand Down
25 changes: 16 additions & 9 deletions packages/ibm-products/src/components/TagSet/TagSet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,24 @@ export let TagSet = React.forwardRef<HTMLDivElement, TagSetProps>(
);

useEffect(() => {
let size = 'md';
// create visible and overflow tags
let newDisplayedTags =
tags && tags.length > 0
? tags.map(({ label, onClose, ...other }, index) => (
<Tag
{...other}
key={`displayed-tag-${index}`}
onClose={() => handleTagOnClose(onClose, index)}
>
{label}
</Tag>
))
? tags.map(({ label, onClose, ...other }, index) => {
if (index == tags.length - 1 && other.size) {
size = other.size;
}
return (
<Tag
{...other}
key={`displayed-tag-${index}`}
onClose={() => handleTagOnClose(onClose, index)}
>
{label}
</Tag>
);
})
: [];

// separate out tags for the overflow
Expand All @@ -266,6 +272,7 @@ export let TagSet = React.forwardRef<HTMLDivElement, TagSetProps>(
overflowAlign={overflowAlign}
overflowType={overflowType}
showAllTagsLabel={showAllTagsLabel}
size={size}
key="displayed-tag-overflow"
ref={overflowTag}
popoverOpen={popoverOpen}
Expand Down
19 changes: 14 additions & 5 deletions packages/ibm-products/src/components/TagSet/TagSetOverflow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import PropTypes from 'prop-types';
import cx from 'classnames';

/**@ts-ignore */
import { Link, Tag, Popover, PopoverContent } from '@carbon/react';
import { Link, Popover, PopoverContent, OperationalTag } from '@carbon/react';
import { useClickOutside } from '../../global/js/hooks';
import { pkg } from '../../settings';

Expand Down Expand Up @@ -83,6 +83,10 @@ interface TagSetOverflowProps {
* label for the overflow show all tags link
*/
showAllTagsLabel?: string;
/**
* Size of the overflow tag
*/
size?: string;
}

export const TagSetOverflow = React.forwardRef(
Expand All @@ -100,6 +104,7 @@ export const TagSetOverflow = React.forwardRef(
showAllTagsLabel,
popoverOpen,
setPopoverOpen,
size,
// Collect any other property values passed in.
...rest
}: PropsWithChildren<TagSetOverflowProps>,
Expand Down Expand Up @@ -149,12 +154,12 @@ export const TagSetOverflow = React.forwardRef(
open={popoverOpen}
autoAlign={overflowAutoAlign}
>
<Tag
<OperationalTag
onClick={() => setPopoverOpen?.(!popoverOpen)}
className={cx(`${blockClass}__popover-trigger`)}
>
{`+${overflowTags.length}`}
</Tag>
size={size}
text={`+${overflowTags.length}`}
/>
<PopoverContent>
<div ref={overflowTagContent} className={`${blockClass}__content`}>
<ul className={`${blockClass}__tag-list`}>
Expand Down Expand Up @@ -265,4 +270,8 @@ TagSetOverflow.propTypes = {
* label for the overflow show all tags link
*/
showAllTagsLabel: PropTypes.string,
/**
* Size of the overflow tag
*/
size: PropTypes.string,
};

0 comments on commit 64602a2

Please sign in to comment.