From 43239102b34d89c9a3e583b39eac18f2a27a682b Mon Sep 17 00:00:00 2001 From: Andrei Zhaleznichenka Date: Fri, 10 Jan 2025 12:00:15 +0100 Subject: [PATCH 1/2] chore: Adds feature metrics for collection prefs and button group --- .../__tests__/button-group-dev.test.tsx | 35 +++++++++++++++++++ src/button-group/index.tsx | 25 +++++++++++++ src/collection-preferences/index.tsx | 1 + 3 files changed, 61 insertions(+) diff --git a/src/button-group/__tests__/button-group-dev.test.tsx b/src/button-group/__tests__/button-group-dev.test.tsx index c9d1d9d66f..503de19418 100644 --- a/src/button-group/__tests__/button-group-dev.test.tsx +++ b/src/button-group/__tests__/button-group-dev.test.tsx @@ -6,10 +6,13 @@ import { fireEvent } from '@testing-library/react'; import { warnOnce } from '@cloudscape-design/component-toolkit/internal'; import { ButtonGroupProps } from '../../../lib/components/button-group'; +import useBaseComponent from '../../../lib/components/internal/hooks/use-base-component'; import { renderButtonGroup } from './common'; import buttonStyles from '../../../lib/components/button/styles.css.js'; +jest.mock('../../../lib/components/internal/hooks/use-base-component', () => jest.fn().mockReturnValue({})); + jest.mock('@cloudscape-design/component-toolkit/internal', () => ({ ...jest.requireActual('@cloudscape-design/component-toolkit/internal'), warnOnce: jest.fn(), @@ -17,6 +20,7 @@ jest.mock('@cloudscape-design/component-toolkit/internal', () => ({ afterEach(() => { (warnOnce as jest.Mock).mockReset(); + (useBaseComponent as jest.Mock).mockReset(); }); const emptyGroup: ButtonGroupProps.ItemOrGroup[] = [ @@ -156,3 +160,34 @@ test('handles file upload', () => { expect(onFilesChange).toHaveBeenCalledWith(expect.objectContaining({ detail: { id: 'file', files: [file] } })); }); + +test('adds feature metrics', () => { + renderButtonGroup({ + items: [ + { type: 'icon-button', id: 'icon1', text: 'icon1' }, + { + type: 'group', + text: 'group1', + items: [ + { type: 'icon-toggle-button', id: 'toggle1', text: 'toggle1', pressed: false }, + { type: 'icon-toggle-button', id: 'toggle2', text: 'toggle2', pressed: false }, + ], + }, + { type: 'icon-file-input', id: 'file1', text: 'file1' }, + { type: 'menu-dropdown', id: 'menu1', text: 'menu1', items: [] }, + ], + }); + expect(useBaseComponent).toHaveBeenCalledWith('ButtonGroup', { + props: { + variant: 'icon', + dropdownExpandToViewport: undefined, + }, + metadata: { + iconButtonsCount: 1, + iconToggleButtonsCount: 2, + iconFileInputsCount: 1, + menuDropdownsCount: 1, + groupsCount: 1, + }, + }); +}); diff --git a/src/button-group/index.tsx b/src/button-group/index.tsx index c9da236c5a..5bfc2cac49 100644 --- a/src/button-group/index.tsx +++ b/src/button-group/index.tsx @@ -14,11 +14,19 @@ export { ButtonGroupProps }; const ButtonGroup = React.forwardRef( ({ variant, dropdownExpandToViewport, ...rest }: ButtonGroupProps, ref: React.Ref) => { const baseProps = getBaseProps(rest); + const itemCounts = getItemCounts(rest.items); const baseComponentProps = useBaseComponent('ButtonGroup', { props: { variant, dropdownExpandToViewport, }, + metadata: { + iconButtonsCount: itemCounts['icon-button'], + iconToggleButtonsCount: itemCounts['icon-toggle-button'], + iconFileInputsCount: itemCounts['icon-file-input'], + menuDropdownsCount: itemCounts['menu-dropdown'], + groupsCount: itemCounts.group, + }, }); const externalProps = getExternalProps(rest); @@ -35,5 +43,22 @@ const ButtonGroup = React.forwardRef( } ); +function getItemCounts(allItems: readonly ButtonGroupProps.ItemOrGroup[]) { + const counters = { 'icon-button': 0, 'icon-toggle-button': 0, 'icon-file-input': 0, 'menu-dropdown': 0, group: 0 }; + + function count(items: readonly ButtonGroupProps.ItemOrGroup[]) { + for (const item of items) { + counters[item.type] += 1; + + if (item.type === 'group') { + count(item.items); + } + } + } + count(allItems); + + return counters; +} + applyDisplayName(ButtonGroup, 'ButtonGroup'); export default ButtonGroup; diff --git a/src/collection-preferences/index.tsx b/src/collection-preferences/index.tsx index 1688ef7e2b..f10e03a94a 100644 --- a/src/collection-preferences/index.tsx +++ b/src/collection-preferences/index.tsx @@ -73,6 +73,7 @@ export default function CollectionPreferences({ hasContentDisplayPreference: !!contentDisplayPreference, hasContentDensityPreference: !!contentDensityPreference, hasStickyColumnsPreference: !!stickyColumnsPreference, + hasContentDisplayColumnFiltering: !!contentDisplayPreference?.enableColumnFiltering, visibleContentOptionsCount: visibleContentPreference?.options?.length, }, }); From 11d58616b42969daa7d9e19543277c00c58b7b58 Mon Sep 17 00:00:00 2001 From: Andrei Zhaleznichenka Date: Fri, 10 Jan 2025 12:10:43 +0100 Subject: [PATCH 2/2] smallfix for internal ssr tests that do not pass items although required --- src/button-group/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/button-group/index.tsx b/src/button-group/index.tsx index 5bfc2cac49..b2d7c88f9e 100644 --- a/src/button-group/index.tsx +++ b/src/button-group/index.tsx @@ -43,7 +43,7 @@ const ButtonGroup = React.forwardRef( } ); -function getItemCounts(allItems: readonly ButtonGroupProps.ItemOrGroup[]) { +function getItemCounts(allItems: readonly ButtonGroupProps.ItemOrGroup[] = []) { const counters = { 'icon-button': 0, 'icon-toggle-button': 0, 'icon-file-input': 0, 'menu-dropdown': 0, group: 0 }; function count(items: readonly ButtonGroupProps.ItemOrGroup[]) {