Skip to content

Commit 27e0583

Browse files
authored
feat: support custom scroll container (#30)
* feat: support custom scroll container * feat: refactor all * feat: refactor all * fix: case sensitive scroll from main * fix: rebase * fix: typo
1 parent d7fd3f3 commit 27e0583

File tree

177 files changed

+903
-283
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+903
-283
lines changed

package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@
1111
"module": "build/esm/index.js",
1212
"types": "types/src/index.d.ts",
1313
"exports": {
14-
".": {
15-
"types": "./types/src/index.d.ts",
16-
"require": "./build/cjs/index.js",
17-
"import": "./build/esm/index.js"
14+
"./window-scroll": {
15+
"types": "./types/src/window-scroll.d.ts",
16+
"require": "./build/cjs/window-scroll.js",
17+
"import": "./build/esm/window-scroll.js"
18+
},
19+
"./container-scroll": {
20+
"types": "./types/src/container-scroll.d.ts",
21+
"require": "./build/cjs/container-scroll.js",
22+
"import": "./build/esm/container-scroll.js"
1823
}
1924
},
2025
"files": [

src/ReactUnipika/ReactUnipika.tsx

Lines changed: 0 additions & 143 deletions
This file was deleted.
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import React from 'react';
2+
3+
// @ts-expect-error
4+
import unipika from '@gravity-ui/unipika/lib/unipika';
5+
6+
import {cn} from '../utils/classname';
7+
import {ReactUnipikaCommonProps} from './types';
8+
import {UnipikaSettings} from '../StructuredYson/types';
9+
import {defaultUnipikaSettings} from './constants';
10+
11+
const block = cn('g-ru-react-unipika');
12+
13+
interface ConvertedValue {
14+
convertedValue?: any;
15+
error?: any;
16+
}
17+
18+
function convertValue(value: any, settings: UnipikaSettings): ConvertedValue {
19+
try {
20+
// TODO: fix me later
21+
// The call is required because unipika.format() applies default values to a passed settings inplace.
22+
// We have to leave this call without it the behaviour will be broken.
23+
if (settings.format === 'raw-json') {
24+
unipika.formatRaw(value, settings);
25+
} else {
26+
unipika.formatFromYSON(value, settings);
27+
}
28+
29+
if (value === undefined) {
30+
return {convertedValue: ''};
31+
}
32+
33+
if (settings.format === 'raw-json') {
34+
return {convertedValue: unipika.converters.raw(value, settings)};
35+
}
36+
37+
return {convertedValue: unipika.converters.yson(value, settings)};
38+
} catch (error) {
39+
return {error};
40+
}
41+
}
42+
43+
interface WithReactUnipikaBaseProps<P extends ReactUnipikaCommonProps> {
44+
renderVirtualized: (props: P, convertedValue: any) => React.ReactNode;
45+
}
46+
47+
export function withReactUnipikaBase<P extends ReactUnipikaCommonProps>(
48+
config: WithReactUnipikaBaseProps<P>,
49+
) {
50+
return function ReactUnipikaBaseComponent(props: P) {
51+
const {
52+
value,
53+
settings = defaultUnipikaSettings,
54+
inline = false,
55+
children,
56+
virtualized = true,
57+
className,
58+
renderError,
59+
} = props;
60+
61+
const {convertedValue, error} = React.useMemo(
62+
() => convertValue(value, settings),
63+
[value, settings],
64+
);
65+
66+
const getFormattedTitle = React.useCallback(() => {
67+
if (!inline) {
68+
return undefined;
69+
}
70+
71+
const titleSettings = Object.assign({}, settings, {asHTML: false});
72+
return unipika.format(convertedValue, titleSettings);
73+
}, [inline, settings, convertedValue]);
74+
75+
const getFormattedValue = React.useCallback(() => {
76+
return unipika.format(convertedValue, settings);
77+
}, [convertedValue, settings]);
78+
79+
const classes = block(
80+
{
81+
inline: inline && 'yes',
82+
},
83+
className,
84+
);
85+
86+
if (error) {
87+
return renderError?.(error);
88+
}
89+
90+
return settings.asHTML ? (
91+
<div className={classes} title={getFormattedTitle()} dir="auto">
92+
{virtualized ? (
93+
config.renderVirtualized(props, convertedValue)
94+
) : (
95+
<pre
96+
className="unipika"
97+
dangerouslySetInnerHTML={{
98+
__html: getFormattedValue(),
99+
}}
100+
/>
101+
)}
102+
{children}
103+
</div>
104+
) : (
105+
<div
106+
className={classes}
107+
title={getFormattedTitle()}
108+
dangerouslySetInnerHTML={{
109+
__html: getFormattedValue(),
110+
}}
111+
dir="auto"
112+
>
113+
{children}
114+
</div>
115+
);
116+
};
117+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
3+
import {StructuredYsonContainerScroll} from '../StructuredYson/StructuredYsonContainerScroll';
4+
import {withReactUnipikaBase} from './ReactUnipikaBase';
5+
import {ReactUnipikaWithScrollContainer} from './types';
6+
import {defaultUnipikaSettings} from './constants';
7+
8+
export const ReactUnipikaContainerScroll = withReactUnipikaBase<ReactUnipikaWithScrollContainer>({
9+
renderVirtualized: (props, convertedValue) => {
10+
const {
11+
settings = defaultUnipikaSettings,
12+
extraTools,
13+
customLayout,
14+
toolbarStickyTop,
15+
renderToolbar,
16+
collapseIconType,
17+
showContainerSize,
18+
initiallyCollapsed,
19+
caseInsensitiveSearch,
20+
scrollContainerRef,
21+
} = props;
22+
23+
return (
24+
<StructuredYsonContainerScroll
25+
value={convertedValue}
26+
settings={settings}
27+
extraTools={extraTools}
28+
customLayout={customLayout}
29+
toolbarStickyTop={toolbarStickyTop}
30+
renderToolbar={renderToolbar}
31+
collapseIconType={collapseIconType}
32+
showContainerSize={showContainerSize}
33+
initiallyCollapsed={initiallyCollapsed}
34+
caseInsensitiveSearch={caseInsensitiveSearch}
35+
scrollContainerRef={scrollContainerRef}
36+
/>
37+
);
38+
},
39+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react';
2+
3+
import {StructuredYsonWindowScroll} from '../StructuredYson/StructuredYsonWindowScroll';
4+
import {withReactUnipikaBase} from './ReactUnipikaBase';
5+
import {ReactUnipikaCommonProps} from './types';
6+
import {defaultUnipikaSettings} from './constants';
7+
8+
export const ReactUnipikaWindowScroll = withReactUnipikaBase<ReactUnipikaCommonProps>({
9+
renderVirtualized: (props, convertedValue) => {
10+
const {
11+
settings = defaultUnipikaSettings,
12+
extraTools,
13+
customLayout,
14+
toolbarStickyTop,
15+
renderToolbar,
16+
collapseIconType,
17+
showContainerSize,
18+
initiallyCollapsed,
19+
caseInsensitiveSearch,
20+
} = props;
21+
22+
return (
23+
<StructuredYsonWindowScroll
24+
value={convertedValue}
25+
settings={settings}
26+
extraTools={extraTools}
27+
customLayout={customLayout}
28+
toolbarStickyTop={toolbarStickyTop}
29+
renderToolbar={renderToolbar}
30+
collapseIconType={collapseIconType}
31+
showContainerSize={showContainerSize}
32+
initiallyCollapsed={initiallyCollapsed}
33+
caseInsensitiveSearch={caseInsensitiveSearch}
34+
/>
35+
);
36+
},
37+
});

0 commit comments

Comments
 (0)