-
Notifications
You must be signed in to change notification settings - Fork 185
/
Copy pathComponentPlayground.tsx
103 lines (94 loc) · 3.7 KB
/
ComponentPlayground.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import * as React from 'react';
import type { AdaptivityProps } from '../../components/AdaptivityProvider/AdaptivityContext';
import { AdaptivityProvider } from '../../components/AdaptivityProvider/AdaptivityProvider';
import { ConfigProvider } from '../../components/ConfigProvider/ConfigProvider';
import { BREAKPOINTS } from '../../lib/adaptivity';
import type { ColorSchemeType } from '../../lib/colorScheme';
import { mapObject } from '../../lib/object';
import type { PlatformType } from '../../lib/platform';
import { AppDefaultWrapper, type AppDefaultWrapperProps } from './AppDefaultWrapper';
import { TEST_CLASS_NAMES } from './constants';
import { getAdaptivePxWidth, isCustomValueWithLabel, multiCartesian, prettyProps } from './utils';
export interface InternalComponentPlaygroundProps<Props = React.ComponentProps<'div'>> {
isFixedComponent?: boolean;
platform: PlatformType;
colorScheme: ColorSchemeType;
adaptivityProviderProps?: Partial<AdaptivityProps>;
propSets?: Parameters<typeof multiCartesian<Props>>[0];
children: (props: Props) => React.ReactNode;
AppWrapper?: React.ComponentType<AppDefaultWrapperProps>;
}
export type ComponentPlaygroundProps = Pick<
InternalComponentPlaygroundProps,
'platform' | 'colorScheme' | 'adaptivityProviderProps'
>;
/**
* Рендерит переданный в `children` компонент с разными параметрами (`propSets`).
*/
export const ComponentPlayground = <
Props extends React.ComponentProps<any> = React.ComponentProps<'div'>,
>({
isFixedComponent = false,
colorScheme,
platform,
adaptivityProviderProps: adaptivityProviderPropsProp,
propSets = [],
children,
AppWrapper = AppDefaultWrapper,
...restProps
}: InternalComponentPlaygroundProps<Props>): React.ReactNode => {
const isVKCOM = platform === 'vkcom';
const adaptivityProviderProps: AdaptivityProps = Object.assign(
isVKCOM ? { sizeX: 'regular', sizeY: 'compact' } : {},
adaptivityProviderPropsProp,
);
const wrapperWidth = adaptivityProviderProps.viewWidth
? getAdaptivePxWidth(adaptivityProviderProps.viewWidth)
: isVKCOM
? 'auto'
: BREAKPOINTS.MOBILE;
return (
<ConfigProvider colorScheme={colorScheme} platform={platform}>
<AdaptivityProvider {...adaptivityProviderProps}>
<AppWrapper
className={TEST_CLASS_NAMES.APP_ROOT}
mode={isFixedComponent ? 'full' : undefined}
style={
isFixedComponent
? undefined
: {
position: 'absolute',
width: wrapperWidth,
height: 'auto',
maxWidth: BREAKPOINTS.DESKTOP,
}
}
{...restProps}
>
{multiCartesian(propSets, { adaptive: !isVKCOM }).map((props, i) => {
const clonedAdaptivityProviderProps = { ...adaptivityProviderProps };
if (props.sizeX) {
clonedAdaptivityProviderProps.sizeX = props.sizeX;
}
if (props.sizeY) {
clonedAdaptivityProviderProps.sizeY = props.sizeY;
}
const mappedProps = mapObject(props, (v) => (isCustomValueWithLabel(v) ? v.value : v));
return (
<React.Fragment key={i}>
{isFixedComponent ? null : (
<div className={TEST_CLASS_NAMES.CONTENT}>{prettyProps(props)}</div>
)}
<div>
<AdaptivityProvider {...clonedAdaptivityProviderProps}>
{children(mappedProps)}
</AdaptivityProvider>
</div>
</React.Fragment>
);
})}
</AppWrapper>
</AdaptivityProvider>
</ConfigProvider>
);
};