@cloudscape-design/components 3.0.332 → 3.0.334
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/button/interfaces.d.ts +2 -1
- package/button/interfaces.d.ts.map +1 -1
- package/button/interfaces.js.map +1 -1
- package/button/internal.d.ts.map +1 -1
- package/button/internal.js +12 -1
- package/button/internal.js.map +1 -1
- package/button/styles.css.js +20 -19
- package/button/styles.scoped.css +223 -137
- package/button/styles.selectors.js +20 -19
- package/button-dropdown/interfaces.d.ts +2 -1
- package/button-dropdown/interfaces.d.ts.map +1 -1
- package/button-dropdown/interfaces.js.map +1 -1
- package/button-dropdown/internal.d.ts.map +1 -1
- package/button-dropdown/internal.js +14 -3
- package/button-dropdown/internal.js.map +1 -1
- package/expandable-section/expandable-section-header.d.ts.map +1 -1
- package/expandable-section/expandable-section-header.js +1 -1
- package/expandable-section/expandable-section-header.js.map +1 -1
- package/expandable-section/styles.css.js +29 -28
- package/expandable-section/styles.scoped.css +59 -56
- package/expandable-section/styles.selectors.js +29 -28
- package/form/internal.d.ts.map +1 -1
- package/form/internal.js +7 -2
- package/form/internal.js.map +1 -1
- package/form-field/internal.d.ts.map +1 -1
- package/form-field/internal.js +8 -3
- package/form-field/internal.js.map +1 -1
- package/internal/analytics/components/analytics-funnel.d.ts.map +1 -1
- package/internal/analytics/components/analytics-funnel.js +58 -11
- package/internal/analytics/components/analytics-funnel.js.map +1 -1
- package/internal/analytics/context/analytics-context.d.ts +5 -1
- package/internal/analytics/context/analytics-context.d.ts.map +1 -1
- package/internal/analytics/context/analytics-context.js +3 -0
- package/internal/analytics/context/analytics-context.js.map +1 -1
- package/internal/analytics/hooks/use-funnel.d.ts +3 -0
- package/internal/analytics/hooks/use-funnel.d.ts.map +1 -1
- package/internal/analytics/hooks/use-funnel.js +7 -2
- package/internal/analytics/hooks/use-funnel.js.map +1 -1
- package/internal/environment.js +1 -1
- package/internal/manifest.json +1 -1
- package/package.json +1 -1
- package/test-utils/dom/expandable-section/index.d.ts +2 -0
- package/test-utils/dom/expandable-section/index.js +7 -0
- package/test-utils/dom/expandable-section/index.js.map +1 -1
- package/test-utils/selectors/expandable-section/index.d.ts +2 -0
- package/test-utils/selectors/expandable-section/index.js +7 -0
- package/test-utils/selectors/expandable-section/index.js.map +1 -1
- package/test-utils/tsconfig.tsbuildinfo +1 -1
|
@@ -14,8 +14,10 @@ export const AnalyticsFunnel = (_a) => {
|
|
|
14
14
|
var { children } = _a, props = __rest(_a, ["children"]);
|
|
15
15
|
const [funnelInteractionId, setFunnelInteractionId] = useState('');
|
|
16
16
|
const [submissionAttempt, setSubmissionAttempt] = useState(0);
|
|
17
|
-
const funnelResultRef = useRef(false);
|
|
18
17
|
const isVisualRefresh = useVisualRefresh();
|
|
18
|
+
const funnelState = useRef('default');
|
|
19
|
+
const errorCount = useRef(0);
|
|
20
|
+
const loadingButtonCount = useRef(0);
|
|
19
21
|
// This useEffect hook is run once on component mount to initiate the funnel analytics.
|
|
20
22
|
// It first calls the 'funnelStart' method from FunnelMetrics, providing all necessary details
|
|
21
23
|
// about the funnel, and receives a unique interaction id.
|
|
@@ -27,6 +29,8 @@ export const AnalyticsFunnel = (_a) => {
|
|
|
27
29
|
// The eslint-disable is required as we deliberately want this effect to run only once on mount and unmount,
|
|
28
30
|
// hence we do not provide any dependencies.
|
|
29
31
|
useEffect(() => {
|
|
32
|
+
// Reset the state, in case the component was re-mounted.
|
|
33
|
+
funnelState.current = 'default';
|
|
30
34
|
const funnelInteractionId = FunnelMetrics.funnelStart({
|
|
31
35
|
funnelNameSelector: getFunnelNameSelector(),
|
|
32
36
|
optionalStepNumbers: props.optionalStepNumbers,
|
|
@@ -37,24 +41,62 @@ export const AnalyticsFunnel = (_a) => {
|
|
|
37
41
|
funnelVersion: FUNNEL_VERSION,
|
|
38
42
|
});
|
|
39
43
|
setFunnelInteractionId(funnelInteractionId);
|
|
44
|
+
/*
|
|
45
|
+
A funnel counts as "successful" if it is unmounted after being "complete".
|
|
46
|
+
*/
|
|
47
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
40
48
|
return () => {
|
|
41
|
-
if (
|
|
49
|
+
if (funnelState.current === 'validating') {
|
|
50
|
+
// Finish the validation phase early.
|
|
51
|
+
FunnelMetrics.funnelComplete({ funnelInteractionId });
|
|
52
|
+
funnelState.current = 'complete';
|
|
53
|
+
}
|
|
54
|
+
if (funnelState.current === 'complete') {
|
|
42
55
|
FunnelMetrics.funnelSuccessful({ funnelInteractionId });
|
|
43
56
|
}
|
|
44
57
|
else {
|
|
45
58
|
FunnelMetrics.funnelCancelled({ funnelInteractionId });
|
|
59
|
+
funnelState.current === 'cancelled';
|
|
46
60
|
}
|
|
47
61
|
};
|
|
48
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
49
62
|
}, []);
|
|
63
|
+
/* eslint-enable react-hooks/exhaustive-deps */
|
|
50
64
|
const funnelSubmit = () => {
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
funnelState.current = 'validating';
|
|
66
|
+
/*
|
|
67
|
+
When the user attempts to submit the form, we wait for 50 milliseconds before checking
|
|
68
|
+
if any form validation errors are present. This value was chosen to give enough time
|
|
69
|
+
for validation and rerendering to occur, but be low enough that the user will not
|
|
70
|
+
be able to take further action in the meantime.
|
|
71
|
+
*/
|
|
72
|
+
const VALIDATION_WAIT_DELAY = 50;
|
|
73
|
+
/*
|
|
74
|
+
Loading is expected to take longer than validation, so we can keep the pressure on the CPU low.
|
|
75
|
+
*/
|
|
76
|
+
const LOADING_WAIT_DELAY = 100;
|
|
77
|
+
const checkForCompleteness = () => {
|
|
78
|
+
if (funnelState.current === 'complete') {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (loadingButtonCount.current > 0) {
|
|
82
|
+
setTimeout(checkForCompleteness, LOADING_WAIT_DELAY);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (errorCount.current === 0) {
|
|
86
|
+
/*
|
|
87
|
+
If no validation errors are rendered, we treat the funnel as complete.
|
|
88
|
+
*/
|
|
89
|
+
FunnelMetrics.funnelComplete({ funnelInteractionId });
|
|
90
|
+
funnelState.current = 'complete';
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
funnelState.current = 'default';
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
setTimeout(checkForCompleteness, VALIDATION_WAIT_DELAY);
|
|
53
97
|
};
|
|
54
98
|
const funnelNextOrSubmitAttempt = () => setSubmissionAttempt(i => i + 1);
|
|
55
|
-
const funnelCancel = () => {
|
|
56
|
-
funnelResultRef.current = false;
|
|
57
|
-
};
|
|
99
|
+
const funnelCancel = () => { };
|
|
58
100
|
const funnelContextValue = {
|
|
59
101
|
funnelInteractionId,
|
|
60
102
|
setFunnelInteractionId,
|
|
@@ -65,11 +107,14 @@ export const AnalyticsFunnel = (_a) => {
|
|
|
65
107
|
funnelCancel,
|
|
66
108
|
submissionAttempt,
|
|
67
109
|
funnelNextOrSubmitAttempt,
|
|
110
|
+
funnelState,
|
|
111
|
+
errorCount,
|
|
112
|
+
loadingButtonCount,
|
|
68
113
|
};
|
|
69
114
|
return React.createElement(FunnelContext.Provider, { value: funnelContextValue }, children);
|
|
70
115
|
};
|
|
71
116
|
export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector }) => {
|
|
72
|
-
const { funnelInteractionId } = useFunnel();
|
|
117
|
+
const { funnelInteractionId, funnelState } = useFunnel();
|
|
73
118
|
const funnelStepProps = { [DATA_ATTR_FUNNEL_STEP]: stepNumber };
|
|
74
119
|
// This useEffect hook is used to track the start and completion of interaction with the step.
|
|
75
120
|
// On mount, if there is a valid funnel interaction id, it calls the 'funnelStepStart' method from FunnelMetrics
|
|
@@ -77,7 +122,7 @@ export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector })
|
|
|
77
122
|
// On unmount, it does a similar thing but this time calling 'funnelStepComplete' to record the completion of the interaction.
|
|
78
123
|
useEffect(() => {
|
|
79
124
|
const stepName = getNameFromSelector(stepNameSelector);
|
|
80
|
-
if (funnelInteractionId) {
|
|
125
|
+
if (funnelInteractionId && funnelState.current === 'default') {
|
|
81
126
|
FunnelMetrics.funnelStepStart({
|
|
82
127
|
funnelInteractionId,
|
|
83
128
|
stepNumber,
|
|
@@ -87,7 +132,8 @@ export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector })
|
|
|
87
132
|
});
|
|
88
133
|
}
|
|
89
134
|
return () => {
|
|
90
|
-
|
|
135
|
+
//eslint-disable-next-line react-hooks/exhaustive-deps
|
|
136
|
+
if (funnelInteractionId && funnelState.current === 'default') {
|
|
91
137
|
FunnelMetrics.funnelStepComplete({
|
|
92
138
|
funnelInteractionId,
|
|
93
139
|
stepNumber,
|
|
@@ -97,6 +143,7 @@ export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector })
|
|
|
97
143
|
});
|
|
98
144
|
}
|
|
99
145
|
};
|
|
146
|
+
//eslint-disable-next-line react-hooks/exhaustive-deps
|
|
100
147
|
}, [funnelInteractionId, stepNumber, stepNameSelector]);
|
|
101
148
|
const contextValue = { funnelInteractionId, stepNumber, stepNameSelector, funnelStepProps };
|
|
102
149
|
return (React.createElement(FunnelStepContext.Provider, { value: contextValue }, typeof children === 'function' ? children(contextValue) : children));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/components/analytics-funnel.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport {\n FunnelStepContext,\n FunnelSubStepContext,\n FunnelContext,\n FunnelContextValue,\n FunnelStepContextValue,\n} from '../context/analytics-context';\nimport { useFunnel, useFunnelStep } from '../hooks/use-funnel';\nimport { useUniqueId } from '../../hooks/use-unique-id';\nimport { useVisualRefresh } from '../../hooks/use-visual-mode';\n\nimport { PACKAGE_VERSION } from '../../environment';\n\nimport { FunnelMetrics } from '../';\nimport { FunnelProps, FunnelStepProps } from '../interfaces';\n\nimport {\n DATA_ATTR_FUNNEL_STEP,\n getFunnelNameSelector,\n getNameFromSelector,\n getSubStepAllSelector,\n getSubStepNameSelector,\n getSubStepSelector,\n} from '../selectors';\n\nexport const FUNNEL_VERSION = '1.0';\n\ntype AnalyticsFunnelProps = { children?: React.ReactNode } & Pick<\n FunnelProps,\n 'funnelType' | 'optionalStepNumbers' | 'totalFunnelSteps'\n>;\n\nexport const AnalyticsFunnel = ({ children, ...props }: AnalyticsFunnelProps) => {\n const [funnelInteractionId, setFunnelInteractionId] = useState<string>('');\n const [submissionAttempt, setSubmissionAttempt] = useState(0);\n const funnelResultRef = useRef<boolean>(false);\n const isVisualRefresh = useVisualRefresh();\n\n // This useEffect hook is run once on component mount to initiate the funnel analytics.\n // It first calls the 'funnelStart' method from FunnelMetrics, providing all necessary details\n // about the funnel, and receives a unique interaction id.\n // This unique interaction id is then stored in the state for further use.\n //\n // On component unmount, it checks whether the funnel was successfully completed.\n // Based on this, it either calls 'funnelComplete' or 'funnelCancelled' method from FunnelMetrics.\n //\n // The eslint-disable is required as we deliberately want this effect to run only once on mount and unmount,\n // hence we do not provide any dependencies.\n useEffect(() => {\n const funnelInteractionId = FunnelMetrics.funnelStart({\n funnelNameSelector: getFunnelNameSelector(),\n optionalStepNumbers: props.optionalStepNumbers,\n funnelType: props.funnelType,\n totalFunnelSteps: props.totalFunnelSteps,\n componentVersion: PACKAGE_VERSION,\n theme: isVisualRefresh ? 'vr' : 'classic',\n funnelVersion: FUNNEL_VERSION,\n });\n\n setFunnelInteractionId(funnelInteractionId);\n\n return () => {\n if (funnelResultRef.current === true) {\n FunnelMetrics.funnelSuccessful({ funnelInteractionId });\n } else {\n FunnelMetrics.funnelCancelled({ funnelInteractionId });\n }\n };\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const funnelSubmit = () => {\n FunnelMetrics.funnelComplete({ funnelInteractionId });\n funnelResultRef.current = true;\n };\n\n const funnelNextOrSubmitAttempt = () => setSubmissionAttempt(i => i + 1);\n\n const funnelCancel = () => {\n funnelResultRef.current = false;\n };\n\n const funnelContextValue: FunnelContextValue = {\n funnelInteractionId,\n setFunnelInteractionId,\n funnelType: props.funnelType,\n optionalStepNumbers: props.optionalStepNumbers,\n totalFunnelSteps: props.totalFunnelSteps,\n funnelSubmit,\n funnelCancel,\n submissionAttempt,\n funnelNextOrSubmitAttempt,\n };\n\n return <FunnelContext.Provider value={funnelContextValue}>{children}</FunnelContext.Provider>;\n};\n\ntype AnalyticsFunnelStepProps = {\n children?: React.ReactNode | ((props: FunnelStepContextValue) => React.ReactNode);\n} & Pick<FunnelStepProps, 'stepNumber' | 'stepNameSelector'>;\n\nexport const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector }: AnalyticsFunnelStepProps) => {\n const { funnelInteractionId } = useFunnel();\n\n const funnelStepProps = { [DATA_ATTR_FUNNEL_STEP]: stepNumber };\n\n // This useEffect hook is used to track the start and completion of interaction with the step.\n // On mount, if there is a valid funnel interaction id, it calls the 'funnelStepStart' method from FunnelMetrics\n // to record the beginning of the interaction with the current step.\n // On unmount, it does a similar thing but this time calling 'funnelStepComplete' to record the completion of the interaction.\n useEffect(() => {\n const stepName = getNameFromSelector(stepNameSelector);\n\n if (funnelInteractionId) {\n FunnelMetrics.funnelStepStart({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n\n return () => {\n if (funnelInteractionId) {\n FunnelMetrics.funnelStepComplete({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n }, [funnelInteractionId, stepNumber, stepNameSelector]);\n\n const contextValue: FunnelStepContextValue = { funnelInteractionId, stepNumber, stepNameSelector, funnelStepProps };\n return (\n <FunnelStepContext.Provider value={contextValue}>\n {typeof children === 'function' ? children(contextValue) : children}\n </FunnelStepContext.Provider>\n );\n};\ninterface AnalyticsFunnelSubStepProps {\n children?: React.ReactNode;\n}\n\nexport const AnalyticsFunnelSubStep = ({ children }: AnalyticsFunnelSubStepProps) => {\n const { funnelInteractionId } = useFunnel();\n const { stepNumber, stepNameSelector } = useFunnelStep();\n\n const subStepId = useUniqueId('substep');\n const subStepSelector = getSubStepSelector(subStepId);\n const subStepNameSelector = getSubStepNameSelector(subStepId);\n\n return (\n <FunnelSubStepContext.Provider\n value={{\n funnelInteractionId,\n stepNumber,\n stepNameSelector,\n subStepSelector,\n subStepNameSelector,\n subStepId,\n }}\n >\n {children}\n </FunnelSubStepContext.Provider>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"analytics-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/components/analytics-funnel.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport {\n FunnelStepContext,\n FunnelSubStepContext,\n FunnelContext,\n FunnelContextValue,\n FunnelStepContextValue,\n FunnelState,\n} from '../context/analytics-context';\nimport { useFunnel, useFunnelStep } from '../hooks/use-funnel';\nimport { useUniqueId } from '../../hooks/use-unique-id';\nimport { useVisualRefresh } from '../../hooks/use-visual-mode';\n\nimport { PACKAGE_VERSION } from '../../environment';\n\nimport { FunnelMetrics } from '../';\nimport { FunnelProps, FunnelStepProps } from '../interfaces';\n\nimport {\n DATA_ATTR_FUNNEL_STEP,\n getFunnelNameSelector,\n getNameFromSelector,\n getSubStepAllSelector,\n getSubStepNameSelector,\n getSubStepSelector,\n} from '../selectors';\n\nexport const FUNNEL_VERSION = '1.0';\n\ntype AnalyticsFunnelProps = { children?: React.ReactNode } & Pick<\n FunnelProps,\n 'funnelType' | 'optionalStepNumbers' | 'totalFunnelSteps'\n>;\n\nexport const AnalyticsFunnel = ({ children, ...props }: AnalyticsFunnelProps) => {\n const [funnelInteractionId, setFunnelInteractionId] = useState<string>('');\n const [submissionAttempt, setSubmissionAttempt] = useState(0);\n const isVisualRefresh = useVisualRefresh();\n const funnelState = useRef<FunnelState>('default');\n const errorCount = useRef<number>(0);\n const loadingButtonCount = useRef<number>(0);\n\n // This useEffect hook is run once on component mount to initiate the funnel analytics.\n // It first calls the 'funnelStart' method from FunnelMetrics, providing all necessary details\n // about the funnel, and receives a unique interaction id.\n // This unique interaction id is then stored in the state for further use.\n //\n // On component unmount, it checks whether the funnel was successfully completed.\n // Based on this, it either calls 'funnelComplete' or 'funnelCancelled' method from FunnelMetrics.\n //\n // The eslint-disable is required as we deliberately want this effect to run only once on mount and unmount,\n // hence we do not provide any dependencies.\n useEffect(() => {\n // Reset the state, in case the component was re-mounted.\n funnelState.current = 'default';\n\n const funnelInteractionId = FunnelMetrics.funnelStart({\n funnelNameSelector: getFunnelNameSelector(),\n optionalStepNumbers: props.optionalStepNumbers,\n funnelType: props.funnelType,\n totalFunnelSteps: props.totalFunnelSteps,\n componentVersion: PACKAGE_VERSION,\n theme: isVisualRefresh ? 'vr' : 'classic',\n funnelVersion: FUNNEL_VERSION,\n });\n\n setFunnelInteractionId(funnelInteractionId);\n\n /*\n A funnel counts as \"successful\" if it is unmounted after being \"complete\".\n */\n /* eslint-disable react-hooks/exhaustive-deps */\n return () => {\n if (funnelState.current === 'validating') {\n // Finish the validation phase early.\n FunnelMetrics.funnelComplete({ funnelInteractionId });\n funnelState.current = 'complete';\n }\n\n if (funnelState.current === 'complete') {\n FunnelMetrics.funnelSuccessful({ funnelInteractionId });\n } else {\n FunnelMetrics.funnelCancelled({ funnelInteractionId });\n funnelState.current === 'cancelled';\n }\n };\n }, []);\n /* eslint-enable react-hooks/exhaustive-deps */\n\n const funnelSubmit = () => {\n funnelState.current = 'validating';\n\n /*\n When the user attempts to submit the form, we wait for 50 milliseconds before checking\n if any form validation errors are present. This value was chosen to give enough time\n for validation and rerendering to occur, but be low enough that the user will not\n be able to take further action in the meantime.\n */\n const VALIDATION_WAIT_DELAY = 50;\n /*\n Loading is expected to take longer than validation, so we can keep the pressure on the CPU low.\n */\n const LOADING_WAIT_DELAY = 100;\n\n const checkForCompleteness = () => {\n if (funnelState.current === 'complete') {\n return;\n }\n\n if (loadingButtonCount.current > 0) {\n setTimeout(checkForCompleteness, LOADING_WAIT_DELAY);\n return;\n }\n\n if (errorCount.current === 0) {\n /*\n If no validation errors are rendered, we treat the funnel as complete.\n */\n FunnelMetrics.funnelComplete({ funnelInteractionId });\n funnelState.current = 'complete';\n } else {\n funnelState.current = 'default';\n }\n };\n\n setTimeout(checkForCompleteness, VALIDATION_WAIT_DELAY);\n };\n\n const funnelNextOrSubmitAttempt = () => setSubmissionAttempt(i => i + 1);\n\n const funnelCancel = () => {};\n\n const funnelContextValue: FunnelContextValue = {\n funnelInteractionId,\n setFunnelInteractionId,\n funnelType: props.funnelType,\n optionalStepNumbers: props.optionalStepNumbers,\n totalFunnelSteps: props.totalFunnelSteps,\n funnelSubmit,\n funnelCancel,\n submissionAttempt,\n funnelNextOrSubmitAttempt,\n funnelState,\n errorCount,\n loadingButtonCount,\n };\n\n return <FunnelContext.Provider value={funnelContextValue}>{children}</FunnelContext.Provider>;\n};\n\ntype AnalyticsFunnelStepProps = {\n children?: React.ReactNode | ((props: FunnelStepContextValue) => React.ReactNode);\n} & Pick<FunnelStepProps, 'stepNumber' | 'stepNameSelector'>;\n\nexport const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector }: AnalyticsFunnelStepProps) => {\n const { funnelInteractionId, funnelState } = useFunnel();\n\n const funnelStepProps = { [DATA_ATTR_FUNNEL_STEP]: stepNumber };\n\n // This useEffect hook is used to track the start and completion of interaction with the step.\n // On mount, if there is a valid funnel interaction id, it calls the 'funnelStepStart' method from FunnelMetrics\n // to record the beginning of the interaction with the current step.\n // On unmount, it does a similar thing but this time calling 'funnelStepComplete' to record the completion of the interaction.\n useEffect(() => {\n const stepName = getNameFromSelector(stepNameSelector);\n\n if (funnelInteractionId && funnelState.current === 'default') {\n FunnelMetrics.funnelStepStart({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n\n return () => {\n //eslint-disable-next-line react-hooks/exhaustive-deps\n if (funnelInteractionId && funnelState.current === 'default') {\n FunnelMetrics.funnelStepComplete({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n //eslint-disable-next-line react-hooks/exhaustive-deps\n }, [funnelInteractionId, stepNumber, stepNameSelector]);\n\n const contextValue: FunnelStepContextValue = { funnelInteractionId, stepNumber, stepNameSelector, funnelStepProps };\n return (\n <FunnelStepContext.Provider value={contextValue}>\n {typeof children === 'function' ? children(contextValue) : children}\n </FunnelStepContext.Provider>\n );\n};\ninterface AnalyticsFunnelSubStepProps {\n children?: React.ReactNode;\n}\n\nexport const AnalyticsFunnelSubStep = ({ children }: AnalyticsFunnelSubStepProps) => {\n const { funnelInteractionId } = useFunnel();\n const { stepNumber, stepNameSelector } = useFunnelStep();\n\n const subStepId = useUniqueId('substep');\n const subStepSelector = getSubStepSelector(subStepId);\n const subStepNameSelector = getSubStepNameSelector(subStepId);\n\n return (\n <FunnelSubStepContext.Provider\n value={{\n funnelInteractionId,\n stepNumber,\n stepNameSelector,\n subStepSelector,\n subStepNameSelector,\n subStepId,\n }}\n >\n {children}\n </FunnelSubStepContext.Provider>\n );\n};\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { MutableRefObject, RefObject } from 'react';
|
|
2
2
|
import { FunnelType } from '../interfaces';
|
|
3
3
|
export interface BaseContextProps {
|
|
4
4
|
funnelInteractionId: string | undefined;
|
|
5
5
|
}
|
|
6
|
+
export type FunnelState = 'default' | 'validating' | 'complete' | 'cancelled';
|
|
6
7
|
export interface FunnelContextValue extends BaseContextProps {
|
|
7
8
|
funnelType: FunnelType;
|
|
8
9
|
optionalStepNumbers: number[];
|
|
@@ -12,6 +13,9 @@ export interface FunnelContextValue extends BaseContextProps {
|
|
|
12
13
|
setFunnelInteractionId: (funnelInteractionId: string) => void;
|
|
13
14
|
submissionAttempt: number;
|
|
14
15
|
funnelNextOrSubmitAttempt: () => void;
|
|
16
|
+
funnelState: RefObject<FunnelState>;
|
|
17
|
+
errorCount: MutableRefObject<number>;
|
|
18
|
+
loadingButtonCount: MutableRefObject<number>;
|
|
15
19
|
}
|
|
16
20
|
export interface FunnelStepContextValue extends BaseContextProps {
|
|
17
21
|
stepNameSelector: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics-context.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"analytics-context.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAiB,MAAM,OAAO,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,CAAC;AAE9E,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,UAAU,EAAE,UAAU,CAAC;IACvB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,sBAAsB,EAAE,CAAC,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IACpC,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACrC,kBAAkB,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,yBAA0B,SAAQ,sBAAsB;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC5E;AAGD,eAAO,MAAM,aAAa,6CAaxB,CAAC;AAEH,eAAO,MAAM,iBAAiB,iDAK5B,CAAC;AAEH,eAAO,MAAM,oBAAoB,oDAQ/B,CAAC"}
|
|
@@ -12,6 +12,9 @@ export const FunnelContext = createContext({
|
|
|
12
12
|
funnelCancel: () => { },
|
|
13
13
|
submissionAttempt: 0,
|
|
14
14
|
funnelNextOrSubmitAttempt: () => { },
|
|
15
|
+
funnelState: { current: 'default' },
|
|
16
|
+
errorCount: { current: 0 },
|
|
17
|
+
loadingButtonCount: { current: 0 },
|
|
15
18
|
});
|
|
16
19
|
export const FunnelStepContext = createContext({
|
|
17
20
|
funnelInteractionId: undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics-context.js","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"analytics-context.js","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,EAA+B,aAAa,EAAE,MAAM,OAAO,CAAC;AAqCnE,0BAA0B;AAC1B,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAqB;IAC7D,mBAAmB,EAAE,SAAS;IAC9B,sBAAsB,EAAE,GAAG,EAAE,GAAE,CAAC;IAChC,UAAU,EAAE,aAAa;IACzB,mBAAmB,EAAE,EAAE;IACvB,gBAAgB,EAAE,CAAC;IACnB,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;IACtB,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;IACtB,iBAAiB,EAAE,CAAC;IACpB,yBAAyB,EAAE,GAAG,EAAE,GAAE,CAAC;IACnC,WAAW,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;IACnC,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;IAC1B,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;CACnC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAyB;IACrE,mBAAmB,EAAE,SAAS;IAC9B,gBAAgB,EAAE,EAAE;IACpB,UAAU,EAAE,CAAC;IACb,eAAe,EAAE,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAA4B;IAC3E,mBAAmB,EAAE,SAAS;IAC9B,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,EAAE;IACpB,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,EAAE;IACvB,eAAe,EAAE,EAAE;CACpB,CAAC,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport { MutableRefObject, RefObject, createContext } from 'react';\nimport { FunnelType } from '../interfaces';\n\nexport interface BaseContextProps {\n funnelInteractionId: string | undefined;\n}\n\nexport type FunnelState = 'default' | 'validating' | 'complete' | 'cancelled';\n\nexport interface FunnelContextValue extends BaseContextProps {\n funnelType: FunnelType;\n optionalStepNumbers: number[];\n totalFunnelSteps: number;\n funnelSubmit: () => void;\n funnelCancel: () => void;\n setFunnelInteractionId: (funnelInteractionId: string) => void;\n submissionAttempt: number;\n funnelNextOrSubmitAttempt: () => void;\n funnelState: RefObject<FunnelState>;\n errorCount: MutableRefObject<number>;\n loadingButtonCount: MutableRefObject<number>;\n}\n\nexport interface FunnelStepContextValue extends BaseContextProps {\n stepNameSelector: string;\n stepNumber: number;\n funnelStepProps?: Record<string, string | number | boolean | undefined>;\n}\n\nexport interface FunnelSubStepContextValue extends FunnelStepContextValue {\n subStepId: string;\n subStepSelector: string;\n subStepNameSelector: string;\n stepNumber: number;\n funnelSubStepProps?: Record<string, string | number | boolean | undefined>;\n}\n\n/* istanbul ignore next */\nexport const FunnelContext = createContext<FunnelContextValue>({\n funnelInteractionId: undefined,\n setFunnelInteractionId: () => {},\n funnelType: 'single-page',\n optionalStepNumbers: [],\n totalFunnelSteps: 0,\n funnelSubmit: () => {},\n funnelCancel: () => {},\n submissionAttempt: 0,\n funnelNextOrSubmitAttempt: () => {},\n funnelState: { current: 'default' },\n errorCount: { current: 0 },\n loadingButtonCount: { current: 0 },\n});\n\nexport const FunnelStepContext = createContext<FunnelStepContextValue>({\n funnelInteractionId: undefined,\n stepNameSelector: '',\n stepNumber: 0,\n funnelStepProps: {},\n});\n\nexport const FunnelSubStepContext = createContext<FunnelSubStepContextValue>({\n funnelInteractionId: undefined,\n subStepId: '',\n stepNumber: 0,\n stepNameSelector: '',\n subStepSelector: '',\n subStepNameSelector: '',\n funnelStepProps: {},\n});\n"]}
|
|
@@ -45,6 +45,9 @@ export declare const useFunnel: () => {
|
|
|
45
45
|
setFunnelInteractionId: (funnelInteractionId: string) => void;
|
|
46
46
|
submissionAttempt: number;
|
|
47
47
|
funnelNextOrSubmitAttempt: () => void;
|
|
48
|
+
funnelState: import("react").RefObject<import("../context/analytics-context").FunnelState>;
|
|
49
|
+
errorCount: import("react").MutableRefObject<number>;
|
|
50
|
+
loadingButtonCount: import("react").MutableRefObject<number>;
|
|
48
51
|
funnelInteractionId: string | undefined;
|
|
49
52
|
funnelProps: Record<string, string | number | boolean | undefined>;
|
|
50
53
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-funnel.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":";AAQA;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"use-funnel.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":";AAQA;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;CAqD5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,qEAGzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;CASrB,CAAC"}
|
|
@@ -18,10 +18,12 @@ export const useFunnelSubStep = () => {
|
|
|
18
18
|
const subStepRef = useRef(null);
|
|
19
19
|
const context = useContext(FunnelSubStepContext);
|
|
20
20
|
const { funnelInteractionId, subStepId, subStepSelector, subStepNameSelector, stepNumber, stepNameSelector } = context;
|
|
21
|
+
const { funnelState } = useFunnel();
|
|
21
22
|
const onFocus = (event) => {
|
|
22
23
|
if (funnelInteractionId &&
|
|
23
24
|
subStepRef.current &&
|
|
24
|
-
(!event.relatedTarget || !subStepRef.current.contains(event.relatedTarget))
|
|
25
|
+
(!event.relatedTarget || !subStepRef.current.contains(event.relatedTarget)) &&
|
|
26
|
+
funnelState.current === 'default') {
|
|
25
27
|
FunnelMetrics.funnelSubStepStart({
|
|
26
28
|
funnelInteractionId,
|
|
27
29
|
subStepSelector,
|
|
@@ -33,7 +35,10 @@ export const useFunnelSubStep = () => {
|
|
|
33
35
|
}
|
|
34
36
|
};
|
|
35
37
|
const onBlur = (event) => {
|
|
36
|
-
if (funnelInteractionId &&
|
|
38
|
+
if (funnelInteractionId &&
|
|
39
|
+
subStepRef.current &&
|
|
40
|
+
!subStepRef.current.contains(event.relatedTarget) &&
|
|
41
|
+
funnelState.current === 'default') {
|
|
37
42
|
FunnelMetrics.funnelSubStepComplete({
|
|
38
43
|
funnelInteractionId,
|
|
39
44
|
subStepSelector,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IACnC,MAAM,UAAU,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IACjD,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAC1G,OAAO,CAAC;IAEV,MAAM,OAAO,GAAG,CAAC,KAAuC,EAAE,EAAE;QAC1D,IACE,mBAAmB;YACnB,UAAU,CAAC,OAAO;YAClB,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAqB,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"use-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IACnC,MAAM,UAAU,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IACjD,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAC1G,OAAO,CAAC;IAEV,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,CAAC;IAEpC,MAAM,OAAO,GAAG,CAAC,KAAuC,EAAE,EAAE;QAC1D,IACE,mBAAmB;YACnB,UAAU,CAAC,OAAO;YAClB,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAqB,CAAC,CAAC;YACnF,WAAW,CAAC,OAAO,KAAK,SAAS,EACjC;YACA,aAAa,CAAC,kBAAkB,CAAC;gBAC/B,mBAAmB;gBACnB,eAAe;gBACf,mBAAmB;gBACnB,UAAU;gBACV,gBAAgB;gBAChB,kBAAkB,EAAE,qBAAqB,EAAE;aAC5C,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,KAAuC,EAAE,EAAE;QACzD,IACE,mBAAmB;YACnB,UAAU,CAAC,OAAO;YAClB,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;YACjD,WAAW,CAAC,OAAO,KAAK,SAAS,EACjC;YACA,aAAa,CAAC,qBAAqB,CAAC;gBAClC,mBAAmB;gBACnB,eAAe;gBACf,mBAAmB;gBACnB,UAAU;gBACV,gBAAgB;gBAChB,kBAAkB,EAAE,qBAAqB,EAAE;aAC5C,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAwB,mBAAmB;QACjE,CAAC,CAAC;YACE,CAAC,wBAAwB,CAAC,EAAE,SAAS;YACrC,OAAO;YACP,MAAM;SACP;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,uBAAS,kBAAkB,EAAE,UAAU,IAAK,OAAO,EAAG;AACxD,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE;IAChC,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,WAAW,GAA0D,OAAO,CAAC,mBAAmB;QACpG,CAAC,CAAC;YACE,CAAC,+BAA+B,CAAC,EAAE,OAAO,CAAC,mBAAmB;SAC/D;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,uBAAS,WAAW,IAAK,OAAO,EAAG;AACrC,CAAC,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useContext, useRef } from 'react';\nimport { FunnelContext, FunnelStepContext, FunnelSubStepContext } from '../context/analytics-context';\nimport { DATA_ATTR_FUNNEL_INTERACTION_ID, DATA_ATTR_FUNNEL_SUBSTEP, getSubStepAllSelector } from '../selectors';\nimport { FunnelMetrics } from '../';\n\n/**\n * Custom React Hook to manage and interact with FunnelSubStep.\n * This hook will provide necessary properties and methods required\n * to track and manage interactions with a FunnelSubStep component.\n *\n * The `onFocus` method is used to track the beginning of interaction with the FunnelSubStep.\n * The `onBlur` method is used to track the completion of interaction with the FunnelSubStep.\n * The subStepId is a unique identifier for the funnel sub-step.\n * The subStepRef is a reference to the DOM element of the funnel sub-step.\n */\nexport const useFunnelSubStep = () => {\n const subStepRef = useRef<HTMLDivElement | null>(null);\n const context = useContext(FunnelSubStepContext);\n const { funnelInteractionId, subStepId, subStepSelector, subStepNameSelector, stepNumber, stepNameSelector } =\n context;\n\n const { funnelState } = useFunnel();\n\n const onFocus = (event: React.FocusEvent<HTMLDivElement>) => {\n if (\n funnelInteractionId &&\n subStepRef.current &&\n (!event.relatedTarget || !subStepRef.current.contains(event.relatedTarget as Node)) &&\n funnelState.current === 'default'\n ) {\n FunnelMetrics.funnelSubStepStart({\n funnelInteractionId,\n subStepSelector,\n subStepNameSelector,\n stepNumber,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n\n const onBlur = (event: React.FocusEvent<HTMLDivElement>) => {\n if (\n funnelInteractionId &&\n subStepRef.current &&\n !subStepRef.current.contains(event.relatedTarget) &&\n funnelState.current === 'default'\n ) {\n FunnelMetrics.funnelSubStepComplete({\n funnelInteractionId,\n subStepSelector,\n subStepNameSelector,\n stepNumber,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n\n const funnelSubStepProps: Record<string, any> = funnelInteractionId\n ? {\n [DATA_ATTR_FUNNEL_SUBSTEP]: subStepId,\n onFocus,\n onBlur,\n }\n : {};\n\n return { funnelSubStepProps, subStepRef, ...context };\n};\n\n/**\n * Custom React Hook to manage and interact with FunnelStep.\n * This hook will provide necessary properties required to track\n * and manage interactions with a FunnelStep component.\n *\n * The 'data-analytics-funnel-step' property of funnelStepProps is used to track the index of the current step in the funnel.\n * The context contains additional properties of the FunnelStep.\n */\nexport const useFunnelStep = () => {\n const context = useContext(FunnelStepContext);\n return context;\n};\n\n/**\n * Custom React Hook to manage and interact with Funnel.\n * This hook will provide necessary properties required to track\n * and manage interactions with a Funnel component.\n *\n * The 'data-analytics-funnel-interaction-id' property of funnelProps is used to track the unique identifier of the current interaction with the funnel.\n */\nexport const useFunnel = () => {\n const context = useContext(FunnelContext);\n const funnelProps: Record<string, string | number | boolean | undefined> = context.funnelInteractionId\n ? {\n [DATA_ATTR_FUNNEL_INTERACTION_ID]: context.funnelInteractionId,\n }\n : {};\n\n return { funnelProps, ...context };\n};\n"]}
|
package/internal/environment.js
CHANGED
package/internal/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -6,4 +6,6 @@ export default class ExpandableSectionWrapper extends ComponentWrapper {
|
|
|
6
6
|
findExpandButton(): ElementWrapper;
|
|
7
7
|
findExpandedContent(): ElementWrapper | null;
|
|
8
8
|
findExpandIcon(): ElementWrapper;
|
|
9
|
+
findHeaderText(): ElementWrapper | null;
|
|
10
|
+
findHeaderDescription(): ElementWrapper | null;
|
|
9
11
|
}
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
const dom_1 = require("@cloudscape-design/test-utils-core/dom");
|
|
6
6
|
const styles_selectors_js_1 = require("../../../expandable-section/styles.selectors.js");
|
|
7
7
|
const styles_selectors_js_2 = require("../../../container/styles.selectors.js");
|
|
8
|
+
const styles_selectors_js_3 = require("../../../header/styles.selectors.js");
|
|
8
9
|
class ExpandableSectionWrapper extends dom_1.ComponentWrapper {
|
|
9
10
|
findHeader() {
|
|
10
11
|
return this.findByClassName(styles_selectors_js_1.default.header);
|
|
@@ -24,6 +25,12 @@ class ExpandableSectionWrapper extends dom_1.ComponentWrapper {
|
|
|
24
25
|
findExpandIcon() {
|
|
25
26
|
return this.findByClassName(styles_selectors_js_1.default['icon-container']);
|
|
26
27
|
}
|
|
28
|
+
findHeaderText() {
|
|
29
|
+
return this.findByClassName(styles_selectors_js_1.default['header-text']);
|
|
30
|
+
}
|
|
31
|
+
findHeaderDescription() {
|
|
32
|
+
return this.findByClassName(styles_selectors_js_3.default.description);
|
|
33
|
+
}
|
|
27
34
|
}
|
|
28
35
|
exports.default = ExpandableSectionWrapper;
|
|
29
36
|
ExpandableSectionWrapper.rootSelector = styles_selectors_js_1.default.root;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/dom/expandable-section/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,gEAA0F;AAC1F,yFAAqE;AACrE,gFAAqE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/dom/expandable-section/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,gEAA0F;AAC1F,yFAAqE;AACrE,gFAAqE;AACrE,6EAA+D;AAE/D,MAAqB,wBAAyB,SAAQ,sBAAgB;IAGpE,UAAU;QACR,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,MAAM,CAAE,CAAC;IAC9C,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,OAAO,CAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,eAAe,CAAC,CAAE,CAAC;IACxD,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,CAAC,IAAI,CACd,aAAa,6BAAM,CAAC,kBAAkB,CAAC,eAAe,6BAAe,CAAC,iBAAiB,CAAC,OAAO,6BAAe,CAAC,OAAO,OAAO,6BAAM,CAAC,kBAAkB,CAAC,EAAE,CAC1J,CAAC;IACJ,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,gBAAgB,CAAC,CAAE,CAAC;IACzD,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,aAAa,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAY,CAAC,WAAW,CAAC,CAAC;IACxD,CAAC;;AAlCH,2CAmCC;AAlCQ,qCAAY,GAAG,6BAAM,CAAC,IAAI,CAAC"}
|
|
@@ -6,4 +6,6 @@ export default class ExpandableSectionWrapper extends ComponentWrapper {
|
|
|
6
6
|
findExpandButton(): ElementWrapper;
|
|
7
7
|
findExpandedContent(): ElementWrapper;
|
|
8
8
|
findExpandIcon(): ElementWrapper;
|
|
9
|
+
findHeaderText(): ElementWrapper;
|
|
10
|
+
findHeaderDescription(): ElementWrapper;
|
|
9
11
|
}
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
const selectors_1 = require("@cloudscape-design/test-utils-core/selectors");
|
|
6
6
|
const styles_selectors_js_1 = require("../../../expandable-section/styles.selectors.js");
|
|
7
7
|
const styles_selectors_js_2 = require("../../../container/styles.selectors.js");
|
|
8
|
+
const styles_selectors_js_3 = require("../../../header/styles.selectors.js");
|
|
8
9
|
class ExpandableSectionWrapper extends selectors_1.ComponentWrapper {
|
|
9
10
|
findHeader() {
|
|
10
11
|
return this.findByClassName(styles_selectors_js_1.default.header);
|
|
@@ -24,6 +25,12 @@ class ExpandableSectionWrapper extends selectors_1.ComponentWrapper {
|
|
|
24
25
|
findExpandIcon() {
|
|
25
26
|
return this.findByClassName(styles_selectors_js_1.default['icon-container']);
|
|
26
27
|
}
|
|
28
|
+
findHeaderText() {
|
|
29
|
+
return this.findByClassName(styles_selectors_js_1.default['header-text']);
|
|
30
|
+
}
|
|
31
|
+
findHeaderDescription() {
|
|
32
|
+
return this.findByClassName(styles_selectors_js_3.default.description);
|
|
33
|
+
}
|
|
27
34
|
}
|
|
28
35
|
exports.default = ExpandableSectionWrapper;
|
|
29
36
|
ExpandableSectionWrapper.rootSelector = styles_selectors_js_1.default.root;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/selectors/expandable-section/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,4EAAgG;AAChG,yFAAqE;AACrE,gFAAqE;AACrE,MAAqB,wBAAyB,SAAQ,4BAAgB;IAEpE,UAAU;QACR,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,MAAM,CAAE,CAAC;IAC9C,CAAC;IACD,WAAW;QACT,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,OAAO,CAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,eAAe,CAAC,CAAE,CAAC;IACxD,CAAC;IACD,mBAAmB;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,6BAAM,CAAC,kBAAkB,CAAC,eAAe,6BAAe,CAAC,iBAAiB,CAAC,OAAO,6BAAe,CAAC,OAAO,OAAO,6BAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC9K,CAAC;IACD,cAAc;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,gBAAgB,CAAC,CAAE,CAAC;IACzD,CAAC;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/test-utils/selectors/expandable-section/index.ts"],"names":[],"mappings":";;AAAA,qEAAqE;AACrE,sCAAsC;AACtC,4EAAgG;AAChG,yFAAqE;AACrE,gFAAqE;AACrE,6EAA+D;AAC/D,MAAqB,wBAAyB,SAAQ,4BAAgB;IAEpE,UAAU;QACR,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,MAAM,CAAE,CAAC;IAC9C,CAAC;IACD,WAAW;QACT,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,OAAO,CAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,eAAe,CAAC,CAAE,CAAC;IACxD,CAAC;IACD,mBAAmB;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,6BAAM,CAAC,kBAAkB,CAAC,eAAe,6BAAe,CAAC,iBAAiB,CAAC,OAAO,6BAAe,CAAC,OAAO,OAAO,6BAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC9K,CAAC;IACD,cAAc;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,gBAAgB,CAAC,CAAE,CAAC;IACzD,CAAC;IACD,cAAc;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAM,CAAC,aAAa,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,qBAAqB;QACnB,OAAO,IAAI,CAAC,eAAe,CAAC,6BAAY,CAAC,WAAW,CAAC,CAAC;IACxD,CAAC;;AA1BH,2CA2BC;AA1BQ,qCAAY,GAAG,6BAAM,CAAC,IAAI,CAAC"}
|