Skip to content

Commit

Permalink
Merge 5e37040 into d0878c1
Browse files Browse the repository at this point in the history
  • Loading branch information
erzhan-temir-mamyrov committed Feb 14, 2023
2 parents d0878c1 + 5e37040 commit 58965af
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 10 deletions.
37 changes: 31 additions & 6 deletions packages/react/src/components/FilterTags/FilterTags.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ import classnames from 'classnames';
import { settings } from '../../constants/Settings';
import { useResize } from '../../internal/UseResizeObserver';

const DEFAULT_OVERFLOW_TEXT = 'More: {n}';

const getFilterTagsOverflowText = (filterCount, i18nProp) => {
if (typeof i18nProp === 'function') {
return i18nProp(filterCount);
}

return i18nProp.replace('{n}', filterCount);
};

const { prefix, iotPrefix } = settings;
/* eslint-disable-next-line react/prop-types */
const DefaultWrapper = React.forwardRef(({ children, i18n, ...props }, ref) => {
Expand All @@ -18,12 +28,21 @@ const DefaultWrapper = React.forwardRef(({ children, i18n, ...props }, ref) => {
});
/* eslint-disable-next-line react/prop-types */
const OverflowTag = ({ children }) => (
<span>
{children} <Close16 />
</span>
<div className={`${iotPrefix}--filtertags-overflow-item__wrapper`}>
<span>{children}</span>
<Close16 />
</div>
);

const FilterTags = ({ children, hasOverflow, id, tagContainer, onChange, i18n, testId }) => {
const FilterTags = ({
children,
hasOverflow,
id,
tagContainer,
onChange,
i18n: i18nProps,
testId,
}) => {
const TagContainer = tagContainer || DefaultWrapper;
const overFlowContainerRef = useRef(null);
useResize(overFlowContainerRef);
Expand All @@ -32,6 +51,8 @@ const FilterTags = ({ children, hasOverflow, id, tagContainer, onChange, i18n, t
const [overflowItems, setOverflowItems] = useState([]);
const [visibleItems, setVisibleItems] = useState(childrenItems);

const { filterTagsOverflowMenuText = DEFAULT_OVERFLOW_TEXT, ...i18n } = i18nProps;

useEffect(
() => {
if (hasOverflow && overFlowContainerRef) {
Expand Down Expand Up @@ -97,7 +118,9 @@ const FilterTags = ({ children, hasOverflow, id, tagContainer, onChange, i18n, t
data-floating-menu-container
className={`${iotPrefix}--filtertags-overflow-menu`}
renderIcon={() => (
<div className={`${prefix}--tag`}>{`More: ${overflowItems.length}`}</div>
<div className={`${prefix}--tag`}>
{getFilterTagsOverflowText(overflowItems.length, filterTagsOverflowMenuText)}
</div>
)}
menuOptionsClass={`${iotPrefix}--filtertags-overflow-items`}
menuOffset={{
Expand Down Expand Up @@ -159,7 +182,9 @@ const defaultProps = {
hasOverflow: true,
tagContainer: null,
onChange: null,
i18n: {},
i18n: {
filterTagsOverflowMenuText: DEFAULT_OVERFLOW_TEXT,
},
testId: 'filter-tags',
};

Expand Down
54 changes: 54 additions & 0 deletions packages/react/src/components/FilterTags/FilterTags.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,58 @@ describe('Filtertags', () => {
userEvent.click(screen.getByText('Hello Daughter'));
expect(mockOnClose).toHaveBeenCalledWith('tag-four');
});

it('will render custom overflow menu text from i18n prop', () => {
const mockOnClose = jest.fn();
render(
<FilterTags
i18n={{
filterTagsOverflowMenuText: (itemCount) => `Hidden items: ${itemCount}`,
}}
>
{tagData.map((tag) => (
<Tag
key={`tag-${tag.id}`}
filter
type={tag.type}
title="Clear Filter"
style={{ marginRight: '1rem' }}
onClose={() => mockOnClose(tag.id)}
>
{tag.text}
</Tag>
))}
</FilterTags>
);
const moreButton = screen.queryByText(/Hidden items:*/);
userEvent.click(moreButton);
expect(screen.getByText('Hello Daughter')).toBeTruthy();
userEvent.click(screen.getByText('Hello Daughter'));
expect(mockOnClose).toHaveBeenCalledWith('tag-four');
});

it('will render text without count substitution if callback parameter is not provided', () => {
const mockOnClose = jest.fn();
render(
<FilterTags
i18n={{
filterTagsOverflowMenuText: () => 'Hidden items',
}}
>
{tagData.map((tag) => (
<Tag
key={`tag-${tag.id}`}
filter
type={tag.type}
title="Clear Filter"
style={{ marginRight: '1rem' }}
onClose={() => mockOnClose(tag.id)}
>
{tag.text}
</Tag>
))}
</FilterTags>
);
expect(screen.getByText('Hidden items')).toBeVisible();
});
});
10 changes: 8 additions & 2 deletions packages/react/src/components/FilterTags/_filter-tags.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

.#{$prefix}--overflow-menu {
width: auto;
min-width: 4.5rem;
height: unset;
}
}

Expand Down Expand Up @@ -36,9 +36,15 @@
}
}

.#{$iot-prefix}--filtertags-overflow-item span {
.#{$iot-prefix}--filtertags-overflow-item__wrapper {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;

span {
width: 90%;
overflow: hidden;
text-overflow: ellipsis;
}
}
4 changes: 4 additions & 0 deletions packages/react/src/components/Table/Table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ export const defaultProps = (baseProps) => ({
toolbarTooltipLabel: 'Toolbar tooltip',
filterRowIconDescription: 'Edit filters',
batchActionsOverflowMenuText: '',
filterTagsOverflowMenuText: '+{n}',
},
error: null,
// TODO: set default in v3. Leaving null for backwards compat. to match 'id' which was
Expand Down Expand Up @@ -956,6 +957,9 @@ const Table = (props) => {
<FilterTags
// TODO: remove id in V3.
testId={`${id || testId}-filter-tags`}
i18n={{
filterTagsOverflowMenuText: i18n.filterTagsOverflowMenuText,
}}
>
{view.advancedFilters
.filter((advFilter) => view.selectedAdvancedFilterIds.includes(advFilter.filterId))
Expand Down
21 changes: 20 additions & 1 deletion packages/react/src/components/Table/Table.main.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
getEditDataFunction,
getRowActionStates,
getAdvancedFilters,
getMoreAdvancedFilters,
getTableKnobs,
getI18nKnobs,
getBatchActions,
Expand Down Expand Up @@ -800,12 +801,18 @@ export const WithFiltering = () => {
}

// Advanced filter settings
let displayOverflowFilterTags;
const [showBuilder, setShowBuilder] = useStoryState(false);
const [advancedFilters, setAdvancedFilters] = useStoryState(
hasAdvancedFilter ? getAdvancedFilters() : undefined
);
const selectedAdvancedFilterIds = hasAdvancedFilter
? object('Active advanced filters (view.selectedAdvancedFilterIds) ☢️', ['story-filter'])
? object(
'Active advanced filters (view.selectedAdvancedFilterIds) ☢️',
displayOverflowFilterTags
? ['story-filter']
: ['story-filter', 'story-filter1', 'story-filter2']
)
: undefined;
const advancedFilterFlyoutOpen = hasAdvancedFilter
? boolean('Show advanced filter flyout (view.toolbar.advancedFilterFlyoutOpen) ☢️', true)
Expand All @@ -816,6 +823,14 @@ export const WithFiltering = () => {
const storyNotice = hasAdvancedFilter ? (
<StoryNotice experimental componentName="StatefulTable with advancedFilters" />
) : null;

if (hasAdvancedFilter) {
displayOverflowFilterTags = boolean(
'Enable overflow menu in filter tags for advanced filters ☢️',
false
);
}

const operands = {
CONTAINS: (a, b) => a.includes(b),
NEQ: (a, b) => a !== b,
Expand Down Expand Up @@ -844,6 +859,10 @@ export const WithFiltering = () => {
})
: data;

if (displayOverflowFilterTags) {
setAdvancedFilters((prevFilters) => [...prevFilters, ...getMoreAdvancedFilters()]);
}

const knobRegeneratedKey = `${JSON.stringify(activeFilters)}`;
return (
<>
Expand Down
48 changes: 48 additions & 0 deletions packages/react/src/components/Table/Table.story.helpers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,54 @@ export const getAdvancedFilters = () => [
},
];

export const getMoreAdvancedFilters = () => [
{
filterId: 'story-filter1',
/** Text for main tilte of page */
filterTitleText:
'string CONTAINS toyota Some really long text to enable overflow menu to display Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ac leo augue. Vivamus id orci arcu.',
/**
* the rules passed into the component. The RuleBuilder is a controlled component, so
* this works the same as passing defaultValue to a controlled input component.
*/
filterRules: {
id: 'kmnhf092gub',
groupLogic: 'ALL',
rules: [
{
id: 'asdadguen87',
columnId: 'string',
operand: 'CONTAINS',
value: 'toyota',
},
],
},
filterColumns: getTableColumns(),
},
{
filterId: 'story-filter2',
/** Text for main tilte of page */
filterTitleText: 'select=option-A',
/**
* the rules passed into the component. The RuleBuilder is a controlled component, so
* this works the same as passing defaultValue to a controlled input component.
*/
filterRules: {
id: '9jf87klobuf',
groupLogic: 'ALL',
rules: [
{
id: 'iijn109fmwhd',
columnId: 'select',
operand: 'CONTAINS',
value: 'option-A',
},
],
},
filterColumns: getTableColumns(),
},
];

const getParsedIntOrUndefined = (value) => {
const parsedValue = Number.parseInt(value, 10);
return Number.isNaN(parsedValue) ? undefined : parsedValue;
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/components/Table/TablePropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ export const I18NPropTypes = PropTypes.shape({
filterRowIconDescription: PropTypes.string,
/** button label for batch action overflow menu */
batchActionsOverflowMenuText: PropTypes.string,
/** overflow menu text callback for truncated filter tags */
filterTagsOverflowMenuText: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
});

export const defaultI18NPropTypes = {
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/components/Table/mdx/Table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ import TableViewDropdownContent from '../TableViewDropdown/TableViewDropdownCont
| loadMoreText | string | 'Load more...' | |
| filterRowIconDescription | string | 'Edit filters' | |
| batchActionsOverflowMenuText | string | | Batch action overflow menu label |
| filterTagsOverflowMenuText | string, func | '+{n}' | {n} is number of hidden filters |
## Source Code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ Map {
"filterDescending": "Sort rows by this header in descending order",
"filterNone": "Unsort rows by this header",
"filterRowIconDescription": "Edit filters",
"filterTagsOverflowMenuText": "+{n}",
"inProgressText": "In progress",
"itemSelected": [Function],
"itemsPerPage": "Items per page:",
Expand Down Expand Up @@ -1336,6 +1337,19 @@ Map {
"filterRowIconDescription": Object {
"type": "string",
},
"filterTagsOverflowMenuText": Object {
"args": Array [
Array [
Object {
"type": "func",
},
Object {
"type": "string",
},
],
],
"type": "oneOfType",
},
"inProgressText": Object {
"type": "string",
},
Expand Down Expand Up @@ -2708,6 +2722,19 @@ Map {
"filterRowIconDescription": Object {
"type": "string",
},
"filterTagsOverflowMenuText": Object {
"args": Array [
Array [
Object {
"type": "func",
},
Object {
"type": "string",
},
],
],
"type": "oneOfType",
},
"inProgressText": Object {
"type": "string",
},
Expand Down Expand Up @@ -31203,7 +31230,9 @@ Map {
"FilterTags" => Object {
"defaultProps": Object {
"hasOverflow": true,
"i18n": Object {},
"i18n": Object {
"filterTagsOverflowMenuText": "More: {n}",
},
"id": "filter-tag-container",
"onChange": null,
"tagContainer": null,
Expand Down

0 comments on commit 58965af

Please sign in to comment.