Skip to content

Commit 58f61d0

Browse files
fralongoFrancesco Longo
andauthored
feat: Add analytics metadata to date input component (#3750)
Co-authored-by: Francesco Longo <[email protected]>
1 parent 9524306 commit 58f61d0

File tree

5 files changed

+119
-4
lines changed

5 files changed

+119
-4
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
import { render } from '@testing-library/react';
5+
6+
import {
7+
activateAnalyticsMetadata,
8+
GeneratedAnalyticsMetadataFragment,
9+
} from '@cloudscape-design/component-toolkit/internal/analytics-metadata';
10+
import { getGeneratedAnalyticsMetadata } from '@cloudscape-design/component-toolkit/internal/analytics-metadata/utils';
11+
12+
import DateInput, { DateInputProps } from '../../../lib/components/date-input';
13+
import FormField from '../../../lib/components/form-field';
14+
import createWrapper from '../../../lib/components/test-utils/dom';
15+
16+
function renderDateInput(props: Partial<DateInputProps>) {
17+
const renderResult = render(<DateInput value="" onChange={() => {}} {...props} />);
18+
return createWrapper(renderResult.container).findDateInput()!;
19+
}
20+
21+
const getComponentMetadata = (label: string, value: string) => {
22+
const metadata: GeneratedAnalyticsMetadataFragment = {
23+
contexts: [
24+
{
25+
type: 'component',
26+
detail: {
27+
name: 'awsui.DateInput',
28+
label,
29+
properties: {
30+
value,
31+
},
32+
},
33+
},
34+
],
35+
};
36+
return metadata;
37+
};
38+
39+
beforeAll(() => {
40+
activateAnalyticsMetadata(true);
41+
});
42+
43+
describe('DateInput renders correct analytics metadata', () => {
44+
describe('on the component', () => {
45+
test('with aria label', () => {
46+
const wrapper = renderDateInput({ value: '2023-12-25', ariaLabel: 'label' });
47+
expect(getGeneratedAnalyticsMetadata(wrapper.getElement())).toEqual(getComponentMetadata('label', '2023-12-25'));
48+
});
49+
test('with empty value', () => {
50+
const wrapper = renderDateInput({ ariaLabel: 'label' });
51+
expect(getGeneratedAnalyticsMetadata(wrapper.getElement())).toEqual(getComponentMetadata('label', ''));
52+
});
53+
test('within a form field', () => {
54+
const formFieldLabel = 'form-field-label';
55+
const renderResult = render(
56+
<FormField label={formFieldLabel}>
57+
<DateInput value="2023-12-25" onChange={() => {}} />
58+
</FormField>
59+
);
60+
const componentElement = createWrapper(renderResult.container).findDateInput()!.getElement();
61+
expect(getGeneratedAnalyticsMetadata(componentElement)).toEqual({
62+
contexts: [
63+
{
64+
type: 'component',
65+
detail: {
66+
name: 'awsui.DateInput',
67+
label: formFieldLabel,
68+
properties: {
69+
value: '2023-12-25',
70+
},
71+
},
72+
},
73+
{
74+
type: 'component',
75+
detail: {
76+
name: 'awsui.FormField',
77+
label: formFieldLabel,
78+
},
79+
},
80+
],
81+
});
82+
});
83+
});
84+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
export interface GeneratedAnalyticsMetadataDateInputComponent {
5+
name: 'awsui.DateInput';
6+
label: string;
7+
properties: {
8+
value: string;
9+
};
10+
}

src/date-input/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const DateInput = React.forwardRef((props: DateInputProps, ref: Ref<DateInputPro
1515
const baseComponentProps = useBaseComponent('DateInput', {
1616
props: { autoFocus: props.autoFocus, readOnly: props.readOnly },
1717
});
18-
return <InternalDateInput {...props} {...baseComponentProps} ref={ref} />;
18+
return <InternalDateInput {...props} {...baseComponentProps} __injectAnalyticsComponentMetadata={true} ref={ref} />;
1919
});
2020

2121
applyDisplayName(DateInput, 'DateInput');

src/date-input/internal.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,25 @@
44
import React, { Ref, useMemo, useRef, useState } from 'react';
55
import clsx from 'clsx';
66

7+
import { getAnalyticsMetadataAttribute } from '@cloudscape-design/component-toolkit/internal/analytics-metadata';
8+
79
import MaskedInput from '../internal/components/masked-input';
810
import { fireNonCancelableEvent, NonCancelableCustomEvent } from '../internal/events';
911
import useForwardFocus from '../internal/hooks/forward-focus';
1012
import { InternalBaseComponentProps } from '../internal/hooks/use-base-component';
1113
import { displayToIso, isoToDisplay } from '../internal/utils/date-time';
1214
import formatDateIso from '../internal/utils/date-time/format-date-iso';
1315
import formatDateLocalized from '../internal/utils/date-time/format-date-localized';
16+
import { GeneratedAnalyticsMetadataDateInputComponent } from './analytics-metadata/interfaces';
1417
import { DateInputProps } from './interfaces';
1518
import { generateMaskArgs, normalizeIsoDateString } from './utils';
1619

1720
import styles from './styles.css.js';
1821

19-
type InternalDateInputProps = DateInputProps & InternalBaseComponentProps;
22+
type InternalDateInputProps = DateInputProps &
23+
InternalBaseComponentProps & {
24+
__injectAnalyticsComponentMetadata?: boolean;
25+
};
2026

2127
const InternalDateInput = React.forwardRef(
2228
(
@@ -30,6 +36,7 @@ const InternalDateInput = React.forwardRef(
3036
format = 'slashed',
3137
inputFormat = 'slashed',
3238
__internalRootRef = null,
39+
__injectAnalyticsComponentMetadata = false,
3340
...props
3441
}: InternalDateInputProps,
3542
ref: Ref<DateInputProps.Ref>
@@ -72,6 +79,14 @@ const InternalDateInput = React.forwardRef(
7279
: isoToDisplay(isoValue);
7380
}, [value, isIso, granularity, locale, usesLongLocalizedValue]);
7481

82+
const componentAnalyticsMetadata: GeneratedAnalyticsMetadataDateInputComponent = {
83+
name: 'awsui.DateInput',
84+
label: 'input',
85+
properties: {
86+
value: value || '',
87+
},
88+
};
89+
7590
return (
7691
<MaskedInput
7792
ref={inputRef}
@@ -88,6 +103,9 @@ const InternalDateInput = React.forwardRef(
88103
showUnmaskedValue={usesLongLocalizedValue}
89104
autoComplete={false}
90105
__internalRootRef={__internalRootRef}
106+
{...(__injectAnalyticsComponentMetadata
107+
? getAnalyticsMetadataAttribute({ component: componentAnalyticsMetadata })
108+
: {})}
91109
/>
92110
);
93111
}

src/input/internal.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import React, { Ref, useRef } from 'react';
44
import clsx from 'clsx';
55

66
import { useMergeRefs } from '@cloudscape-design/component-toolkit/internal';
7-
import { getAnalyticsMetadataAttribute } from '@cloudscape-design/component-toolkit/internal/analytics-metadata';
7+
import {
8+
copyAnalyticsMetadataAttribute,
9+
getAnalyticsMetadataAttribute,
10+
} from '@cloudscape-design/component-toolkit/internal/analytics-metadata';
811

912
import InternalButton from '../button/internal';
1013
import { useInternalI18n } from '../i18n/context';
@@ -198,7 +201,7 @@ function InternalInput(
198201
dir={type === 'email' ? 'ltr' : undefined}
199202
{...(__injectAnalyticsComponentMetadata
200203
? getAnalyticsMetadataAttribute({ component: componentAnalyticsMetadata })
201-
: {})}
204+
: copyAnalyticsMetadataAttribute(rest))}
202205
>
203206
{__leftIcon && (
204207
<span onClick={__onLeftIconClick} className={styles['input-icon-left']}>

0 commit comments

Comments
 (0)