@oanda/labs-widget-common 1.0.218 → 1.0.220
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/CHANGELOG.md +1732 -0
- package/dist/main/chart/BaseChart.js +7 -2
- package/dist/main/chart/BaseChart.js.map +1 -1
- package/dist/main/components/Disclaimer/Disclaimer.js +30 -28
- package/dist/main/components/Disclaimer/Disclaimer.js.map +1 -1
- package/dist/main/components/WidgetWrapper/WidgetWrapper.js +7 -2
- package/dist/main/components/WidgetWrapper/WidgetWrapper.js.map +1 -1
- package/dist/main/tailwind/colors.js +3 -1
- package/dist/main/tailwind/colors.js.map +1 -1
- package/dist/main/tailwind/preset.js +2 -1
- package/dist/main/tailwind/preset.js.map +1 -1
- package/dist/module/chart/BaseChart.js +7 -2
- package/dist/module/chart/BaseChart.js.map +1 -1
- package/dist/module/components/Disclaimer/Disclaimer.js +28 -27
- package/dist/module/components/Disclaimer/Disclaimer.js.map +1 -1
- package/dist/module/components/WidgetWrapper/WidgetWrapper.js +7 -2
- package/dist/module/components/WidgetWrapper/WidgetWrapper.js.map +1 -1
- package/dist/module/tailwind/colors.js +3 -1
- package/dist/module/tailwind/colors.js.map +1 -1
- package/dist/module/tailwind/preset.js +2 -1
- package/dist/module/tailwind/preset.js.map +1 -1
- package/dist/types/components/Disclaimer/Disclaimer.d.ts +5 -1
- package/dist/types/components/WidgetWrapper/WidgetWrapper.d.ts +5 -0
- package/dist/types/tailwind/colors.d.ts +4 -0
- package/package.json +2 -2
- package/src/chart/BaseChart.tsx +21 -12
- package/src/components/Disclaimer/Disclaimer.tsx +80 -42
- package/src/components/WidgetWrapper/WidgetWrapper.tsx +10 -0
- package/src/tailwind/colors.ts +2 -0
- package/src/tailwind/preset.ts +1 -0
- package/test/chart/BaseChart.test.tsx +12 -6
|
@@ -22,10 +22,12 @@ export declare const colorPalette: {
|
|
|
22
22
|
white: string;
|
|
23
23
|
black: string;
|
|
24
24
|
grayLight: string;
|
|
25
|
+
grayLight95: string;
|
|
25
26
|
gray: string;
|
|
26
27
|
darkGray: string;
|
|
27
28
|
brightBlue: string;
|
|
28
29
|
brightBlue30: string;
|
|
30
|
+
darkBlue: string;
|
|
29
31
|
};
|
|
30
32
|
export declare const twColorPallete: {
|
|
31
33
|
"red-Dark-": string;
|
|
@@ -50,9 +52,11 @@ export declare const twColorPallete: {
|
|
|
50
52
|
"white-": string;
|
|
51
53
|
"black-": string;
|
|
52
54
|
"gray-Light-": string;
|
|
55
|
+
"gray-Light-9-5-": string;
|
|
53
56
|
"gray-": string;
|
|
54
57
|
"dark-Gray-": string;
|
|
55
58
|
"bright-Blue-": string;
|
|
56
59
|
"bright-Blue-3-0-": string;
|
|
60
|
+
"dark-Blue-": string;
|
|
57
61
|
};
|
|
58
62
|
export type ColorCode = ValueOf<typeof colorPalette>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oanda/labs-widget-common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.220",
|
|
4
4
|
"description": "Labs Widget Common",
|
|
5
5
|
"main": "dist/main/index.js",
|
|
6
6
|
"module": "dist/module/index.js",
|
|
@@ -21,5 +21,5 @@
|
|
|
21
21
|
"tailwind-merge": "2.2.2",
|
|
22
22
|
"usehooks-ts": "3.0.2"
|
|
23
23
|
},
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "84d9bec88af7893f20ccd2d88fcbc28dd30aec22"
|
|
25
25
|
}
|
package/src/chart/BaseChart.tsx
CHANGED
|
@@ -18,18 +18,27 @@ export const BaseChart = forwardRef<BaseChartRef, BaseChartProps>(
|
|
|
18
18
|
}, []);
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
21
|
+
<>
|
|
22
|
+
{ready ? (
|
|
23
|
+
<ReactEChartsCore
|
|
24
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
25
|
+
{...props}
|
|
26
|
+
ref={ref}
|
|
27
|
+
data-testid="charts-container"
|
|
28
|
+
style={{
|
|
29
|
+
height: `${chartHeight}px`,
|
|
30
|
+
width: '100%',
|
|
31
|
+
}}
|
|
32
|
+
theme={isDark ? 'dark_theme' : 'light_theme'}
|
|
33
|
+
/>
|
|
34
|
+
) : (
|
|
35
|
+
<div
|
|
36
|
+
className="lw-w-full"
|
|
37
|
+
data-testid="charts-placeholder"
|
|
38
|
+
style={{ height: `${chartHeight}px` }}
|
|
39
|
+
/>
|
|
40
|
+
)}
|
|
41
|
+
</>
|
|
33
42
|
);
|
|
34
43
|
}
|
|
35
44
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FC, PropsWithChildren } from 'react';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
3
|
|
|
4
4
|
import { OandaLogoDark, OandaLogoLight } from '../../images';
|
|
5
5
|
import { useLayoutProvider } from '../../providers';
|
|
@@ -7,22 +7,12 @@ import { cn } from '../../tailwind';
|
|
|
7
7
|
import type { RenderComponentParams } from '../../types';
|
|
8
8
|
import { Theme } from '../../types';
|
|
9
9
|
|
|
10
|
-
const disclaimerStyles: Record<
|
|
11
|
-
Theme,
|
|
12
|
-
{ wrapperStyle: string; borderStyle: string }
|
|
13
|
-
> = {
|
|
14
|
-
dark: {
|
|
15
|
-
wrapperStyle: 'lw-h-6 lw-bg-[#262F3C]',
|
|
16
|
-
borderStyle: 'lw-border-[#262F3C]',
|
|
17
|
-
},
|
|
18
|
-
light: {
|
|
19
|
-
wrapperStyle: 'lw-shadow-[0_2px_8px_0_rgba(0,33,74,0.25)]',
|
|
20
|
-
borderStyle: 'lw-border-[#e6e6e6]',
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
|
|
24
10
|
type DisclaimerProps = PropsWithChildren &
|
|
25
|
-
Omit<RenderComponentParams, 'Component'
|
|
11
|
+
Omit<RenderComponentParams, 'Component'> & {
|
|
12
|
+
text?: string;
|
|
13
|
+
isSlim?: boolean;
|
|
14
|
+
infoButtonPosition?: 'left' | 'top';
|
|
15
|
+
};
|
|
26
16
|
|
|
27
17
|
export const Disclaimer: FC<DisclaimerProps> = ({
|
|
28
18
|
children,
|
|
@@ -30,23 +20,28 @@ export const Disclaimer: FC<DisclaimerProps> = ({
|
|
|
30
20
|
brandingSpace,
|
|
31
21
|
fitContent = false,
|
|
32
22
|
linkArea = 'full',
|
|
23
|
+
text,
|
|
24
|
+
isSlim,
|
|
25
|
+
infoButtonPosition = 'top',
|
|
33
26
|
}) => {
|
|
34
27
|
const { theme } = useLayoutProvider();
|
|
28
|
+
const isDark = theme === Theme.Dark;
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
const [isLogoHovered, setIsLogoHovered] = useState(false);
|
|
31
|
+
const [isInfoHovered, setIsInfoHovered] = useState(false);
|
|
32
|
+
|
|
33
|
+
if (!logoLink && !text) {
|
|
37
34
|
return children;
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
const isDark = theme !== 'light';
|
|
41
37
|
const isClickable = linkArea === 'full';
|
|
42
|
-
const { wrapperStyle, borderStyle } = disclaimerStyles[theme ?? Theme.Light];
|
|
43
38
|
|
|
44
39
|
return (
|
|
45
40
|
<div
|
|
46
41
|
className={cn(
|
|
47
42
|
'lw-relative lw-overflow-hidden',
|
|
48
43
|
isClickable && 'lw-cursor-pointer',
|
|
49
|
-
brandingSpace && brandingSpace === 'vertical' ? 'lw-pb-12' : 'lw-pb-
|
|
44
|
+
brandingSpace && brandingSpace === 'vertical' ? 'lw-pb-12' : 'lw-pb-0',
|
|
50
45
|
!!fitContent && 'lw-w-fit'
|
|
51
46
|
)}
|
|
52
47
|
data-testid="disclaimer-wrapper"
|
|
@@ -54,34 +49,77 @@ export const Disclaimer: FC<DisclaimerProps> = ({
|
|
|
54
49
|
onClick={() => isClickable && window.open(logoLink, '_blank')}
|
|
55
50
|
>
|
|
56
51
|
{children}
|
|
57
|
-
|
|
58
|
-
className={cn(
|
|
59
|
-
'lw-absolute lw-z-20 lw-bottom-3 lw-right-1 lw-translate-x-[3.7rem] lw-rounded-l-full lw-transition lw-delay-150 lw-duration-300 lw-ease-in-out hover:lw-translate-x-2 [&:hover+div]:lw-translate-x-[3.7rem]',
|
|
60
|
-
wrapperStyle
|
|
61
|
-
)}
|
|
62
|
-
>
|
|
52
|
+
{text && (
|
|
63
53
|
<div
|
|
64
|
-
className=
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
e.stopPropagation();
|
|
69
|
-
window.open(logoLink, '_blank');
|
|
70
|
-
}}
|
|
71
|
-
>
|
|
72
|
-
{isDark ? (
|
|
73
|
-
<OandaLogoDark data-testid="disclaimer-wrapper-logo-dark" />
|
|
74
|
-
) : (
|
|
75
|
-
<OandaLogoLight data-testid="disclaimer-wrapper-logo-light" />
|
|
54
|
+
className={cn(
|
|
55
|
+
'lw-absolute lw-right-0 lw-top-0 lw-z-30 lw-flex lw-h-full lw-items-center lw-bg-border-primary lw-bg-opacity-90 lw-p-3 lw-text-sm lw-text-text-primary lw-delay-150 lw-duration-150 lw-ease-in-out',
|
|
56
|
+
isInfoHovered && 'lw-opacity-100',
|
|
57
|
+
!isInfoHovered && 'lw-opacity-0 lw-pointer-events-none'
|
|
76
58
|
)}
|
|
59
|
+
onBlur={() => setIsInfoHovered(false)}
|
|
60
|
+
onMouseOut={() => setIsInfoHovered(false)}
|
|
61
|
+
>
|
|
62
|
+
{text}
|
|
77
63
|
</div>
|
|
78
|
-
|
|
64
|
+
)}
|
|
79
65
|
<div
|
|
80
66
|
className={cn(
|
|
81
|
-
'lw-absolute lw-bottom-
|
|
82
|
-
|
|
67
|
+
'lw-absolute lw-bottom-3 lw-right-0 lw-z-20 lw-flex lw-transition lw-delay-100 lw-duration-300 lw-ease-in-out',
|
|
68
|
+
logoLink &&
|
|
69
|
+
!isLogoHovered &&
|
|
70
|
+
infoButtonPosition === 'left' &&
|
|
71
|
+
'lw-translate-x-[55px]',
|
|
72
|
+
isSlim && 'lw-bottom-[6px]',
|
|
73
|
+
!isSlim && 'lw-bottom-2',
|
|
74
|
+
infoButtonPosition === 'left' && 'lw-flex-row lw-items-center',
|
|
75
|
+
infoButtonPosition === 'top' && 'lw-flex-col lw-items-end'
|
|
83
76
|
)}
|
|
84
|
-
|
|
77
|
+
>
|
|
78
|
+
{text && (
|
|
79
|
+
<div
|
|
80
|
+
className={cn(
|
|
81
|
+
'lw-flex lw-h-[20px] lw-w-[20px] lw-items-center lw-justify-center lw-rounded-full lw-border lw-border-border-primary lw-pb-0.5 lw-text-sm lw-font-bold lw-text-text-secondary lw-shadow-basic',
|
|
82
|
+
isDark && 'lw-bg-dark-blue',
|
|
83
|
+
!isDark && 'lw-bg-bg-primary',
|
|
84
|
+
infoButtonPosition === 'top' && 'lw-mr-1',
|
|
85
|
+
infoButtonPosition === 'top' && !!logoLink && 'lw-mb-3',
|
|
86
|
+
infoButtonPosition === 'left' && 'lw-mr-2 '
|
|
87
|
+
)}
|
|
88
|
+
onFocus={() => setIsInfoHovered(true)}
|
|
89
|
+
onMouseOver={() => setIsInfoHovered(true)}
|
|
90
|
+
>
|
|
91
|
+
i
|
|
92
|
+
</div>
|
|
93
|
+
)}
|
|
94
|
+
{logoLink && (
|
|
95
|
+
<div
|
|
96
|
+
className={cn(
|
|
97
|
+
'lw-cursor-pointer lw-rounded-l-full lw-bg-bg-primary lw-shadow-basic',
|
|
98
|
+
infoButtonPosition === 'top' &&
|
|
99
|
+
'lw-transition lw-delay-100 lw-duration-300 lw-ease-in-out',
|
|
100
|
+
!isLogoHovered &&
|
|
101
|
+
infoButtonPosition === 'top' &&
|
|
102
|
+
'lw-translate-x-[55px]'
|
|
103
|
+
)}
|
|
104
|
+
data-testid="disclaimer-wrapper-logo"
|
|
105
|
+
role="presentation"
|
|
106
|
+
onBlur={() => setIsLogoHovered(false)}
|
|
107
|
+
onClick={(e) => {
|
|
108
|
+
e.stopPropagation();
|
|
109
|
+
window.open(logoLink, '_blank');
|
|
110
|
+
}}
|
|
111
|
+
onFocus={() => setIsLogoHovered(true)}
|
|
112
|
+
onMouseOut={() => setIsLogoHovered(false)}
|
|
113
|
+
onMouseOver={() => setIsLogoHovered(true)}
|
|
114
|
+
>
|
|
115
|
+
{isDark ? (
|
|
116
|
+
<OandaLogoDark data-testid="disclaimer-wrapper-logo-dark" />
|
|
117
|
+
) : (
|
|
118
|
+
<OandaLogoLight data-testid="disclaimer-wrapper-logo-light" />
|
|
119
|
+
)}
|
|
120
|
+
</div>
|
|
121
|
+
)}
|
|
122
|
+
</div>
|
|
85
123
|
</div>
|
|
86
124
|
);
|
|
87
125
|
};
|
|
@@ -8,6 +8,11 @@ import { WidgetError } from '../Error';
|
|
|
8
8
|
export type WidgetWrapperProps = PropsWithChildren &
|
|
9
9
|
WidgetLink & {
|
|
10
10
|
isParamError?: boolean | undefined;
|
|
11
|
+
disclaimer?: {
|
|
12
|
+
position?: 'left' | 'top';
|
|
13
|
+
text?: string;
|
|
14
|
+
};
|
|
15
|
+
isSlim?: boolean;
|
|
11
16
|
} & Pick<WidgetStyling, 'brandingSpace' | 'fitContent'>;
|
|
12
17
|
|
|
13
18
|
export const WidgetWrapper: FC<WidgetWrapperProps> = ({
|
|
@@ -17,12 +22,17 @@ export const WidgetWrapper: FC<WidgetWrapperProps> = ({
|
|
|
17
22
|
brandingSpace,
|
|
18
23
|
fitContent,
|
|
19
24
|
isParamError,
|
|
25
|
+
disclaimer,
|
|
26
|
+
isSlim,
|
|
20
27
|
}) => (
|
|
21
28
|
<Disclaimer
|
|
22
29
|
brandingSpace={brandingSpace}
|
|
23
30
|
fitContent={fitContent}
|
|
31
|
+
infoButtonPosition={disclaimer?.position}
|
|
32
|
+
isSlim={isSlim}
|
|
24
33
|
linkArea={linkArea}
|
|
25
34
|
logoLink={logoLink}
|
|
35
|
+
text={disclaimer?.text}
|
|
26
36
|
>
|
|
27
37
|
{isParamError ? <WidgetError /> : children}
|
|
28
38
|
</Disclaimer>
|
package/src/tailwind/colors.ts
CHANGED
|
@@ -24,10 +24,12 @@ export const colorPalette = {
|
|
|
24
24
|
white: '#FFFFFF',
|
|
25
25
|
black: '#000000',
|
|
26
26
|
grayLight: '#9EA4AC',
|
|
27
|
+
grayLight95: 'rgba(158, 164, 172, 0.95)',
|
|
27
28
|
gray: '#7B8085',
|
|
28
29
|
darkGray: '#1C1C1C',
|
|
29
30
|
brightBlue: 'rgba(51, 88, 255, 0)',
|
|
30
31
|
brightBlue30: 'rgba(51, 88, 255, 0.3)',
|
|
32
|
+
darkBlue: '#262f3c',
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
export const twColorPallete = toTwConfigKeys(colorPalette);
|
package/src/tailwind/preset.ts
CHANGED
|
@@ -58,22 +58,23 @@ describe('BaseChart component', () => {
|
|
|
58
58
|
|
|
59
59
|
it('should show loading state initially', () => {
|
|
60
60
|
render(<BaseChart {...defaultProps} />);
|
|
61
|
-
const
|
|
62
|
-
expect(
|
|
61
|
+
const placeholder = screen.getByTestId('charts-placeholder');
|
|
62
|
+
expect(placeholder).toBeInTheDocument();
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
it('should render chart after fonts are ready', async () => {
|
|
66
66
|
render(<BaseChart {...defaultProps} />);
|
|
67
67
|
|
|
68
|
-
const
|
|
69
|
-
expect(
|
|
68
|
+
const placeholder = screen.getByTestId('charts-placeholder');
|
|
69
|
+
expect(placeholder).toBeInTheDocument();
|
|
70
70
|
|
|
71
71
|
await act(async () => {
|
|
72
72
|
resolveFontsReady();
|
|
73
73
|
await document.fonts.ready;
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
const chart = screen.getByTestId('charts-container');
|
|
77
|
+
expect(chart).toBeInTheDocument();
|
|
77
78
|
});
|
|
78
79
|
|
|
79
80
|
it('should apply dark theme when isDark is true', async () => {
|
|
@@ -113,9 +114,14 @@ describe('BaseChart component', () => {
|
|
|
113
114
|
expect(chart).toHaveStyle({ height: `${height}px` });
|
|
114
115
|
});
|
|
115
116
|
|
|
116
|
-
it('should forward ref to BaseChartRef', () => {
|
|
117
|
+
it('should forward ref to BaseChartRef', async () => {
|
|
117
118
|
const ref = React.createRef<BaseChartRef>();
|
|
118
119
|
render(<BaseChart {...defaultProps} ref={ref} />);
|
|
120
|
+
|
|
121
|
+
await act(async () => {
|
|
122
|
+
resolveFontsReady();
|
|
123
|
+
await document.fonts.ready;
|
|
124
|
+
});
|
|
119
125
|
expect(ref.current).toBeTruthy();
|
|
120
126
|
});
|
|
121
127
|
});
|