Skip to content

Commit

Permalink
feat: change lib structure (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
korvin89 authored Jun 28, 2022
1 parent 303ed9c commit dfb6ed8
Show file tree
Hide file tree
Showing 27 changed files with 236 additions and 111 deletions.
3 changes: 3 additions & 0 deletions .storybook/decorators/withLang.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React from 'react';
import {Story as StoryType, StoryContext} from '@storybook/react';
import {settings} from '../../src/libs';

export function withLang(Story: StoryType, context: StoryContext) {
const lang = context.globals.lang;

settings.set({lang});

return <Story key={lang} {...context} />;
}
12 changes: 12 additions & 0 deletions src/@types/widget.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type Yagr from 'yagr';
import type {YagrWidgetData} from '../plugins/yagr/types';
import '../types';

declare module '../types' {
export interface ChartkitWidget {
yagr: {
data: YagrWidgetData;
widget: Yagr;
};
}
}
65 changes: 22 additions & 43 deletions src/components/ChartKit.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,29 @@
import React from 'react';
import moment from 'moment';
import {YagrWidget} from './components/YagrWidget/YagrWidget';
import {ErrorComponent} from './components/ErrorComponent/ErrorComponent';
import './ChartKit.scss';
import {ChartKitProps, OnLoadData} from '../types';

function init(lang = 'ru') {
moment.updateLocale(lang, {week: {dow: 1, doy: 7}});
moment.locale(lang);
}
import {settings} from '../libs';
import {getRandomCKId} from '../utils';
import type {ChartkitType, ChartKitProps} from '../types';
import {ErrorBoundary} from './ErrorBoundary/ErrorBoundary';
import {Loader} from './Loader/Loader';

export class ChartKit extends React.Component<ChartKitProps> {
isInit = false;
import './ChartKit.scss';

constructor(props: ChartKitProps) {
super(props);
export const ChartKit = <T extends ChartkitType>(props: ChartKitProps<T>) => {
const {id = getRandomCKId(), type, data, onLoad, ...restProps} = props;
const lang = settings.get('lang');
const plugins = settings.get('plugins');
const plugin = plugins.find((iteratedPlugin) => iteratedPlugin.type === type);

if (!this.isInit) {
init(this.props.lang);
this.isInit = true;
}
if (!plugin) {
return null;
}

onLoad = ({widget = null, widgetRendering = null}: OnLoadData = {}) => {
if (this.props.onLoad) {
this.props.onLoad({
widget,
widgetRendering,
});
}
};
const ChartComponent = plugin.renderer;

render() {
if (this.props.type !== 'yagr') {
return <ErrorComponent lang={this.props.lang} />;
}

return (
<div className={'chartkit chartkit-theme'}>
<YagrWidget
id={this.props.id}
lang={this.props.lang}
data={this.props.data}
onLoad={this.onLoad}
/>
</div>
);
}
}
return (
<ErrorBoundary>
<React.Suspense fallback={<Loader />}>
<ChartComponent id={id} lang={lang} data={data} onLoad={onLoad} {...restProps} />
</React.Suspense>
</ErrorBoundary>
);
};
24 changes: 24 additions & 0 deletions src/components/ErrorBoundary/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import {ErrorView} from '../ErrorView/ErrorView';

type State = {
error?: Error;
};

export class ErrorBoundary extends React.Component<{}, State> {
static getDerivedStateFromError(error: Error) {
return {error};
}

state: State = {
error: undefined,
};

render() {
if (this.state.error) {
return <ErrorView />;
}

return this.props.children;
}
}
File renamed without changes.
16 changes: 16 additions & 0 deletions src/components/ErrorView/ErrorView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import {dict} from '../../dict/dict';
import {settings} from '../../libs';

import './ErrorView.scss';

export const ErrorView = () => {
const lang = settings.get('lang');

return (
<div className={'chartkit-error'}>
<div className={'chartkit-error__title'}>{dict(lang, 'error')}</div>
<div className={'message'}>{dict(lang, 'error-unknown-extension')}</div>
</div>
);
};
7 changes: 7 additions & 0 deletions src/components/Loader/Loader.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.chartkit-loader {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
14 changes: 14 additions & 0 deletions src/components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import {Loader as BaseLoader, LoaderProps as BaseLoaderProps} from '@yandex-cloud/uikit';

import './Loader.scss';

type LoaderProps = BaseLoaderProps;

export const Loader = (props: LoaderProps) => {
return (
<div className="chartkit-loader">
<BaseLoader {...props} />
</div>
);
};
16 changes: 0 additions & 16 deletions src/components/__stories__/Yagr.stories.tsx

This file was deleted.

16 changes: 0 additions & 16 deletions src/components/components/ErrorComponent/ErrorComponent.tsx

This file was deleted.

1 change: 1 addition & 0 deletions src/libs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {settings} from './settings/settings';
57 changes: 57 additions & 0 deletions src/libs/settings/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import moment from 'moment';
import {ChartKitPlugin, ChartKitLang} from '../../types';

type Settings = {
plugins: ChartKitPlugin[];
lang: ChartKitLang;
locale?: moment.LocaleSpecification;
};
type SettingKey = keyof Settings;

const DEFAULT_LOCALE_SPECIFICATION: moment.LocaleSpecification = {week: {dow: 1, doy: 7}};

const removeUndefinedValues = <T extends Record<string, any>>(data: T) => {
return Object.entries(data).reduce((acc, [key, value]) => {
if (typeof value !== 'undefined') {
acc[key as keyof T] = value;
}

return acc;
}, {} as T);
};

const updateLocale = (args: {lang: ChartKitLang; locale?: moment.LocaleSpecification}) => {
const {lang, locale} = args;
moment.updateLocale(lang, locale);
moment.locale(lang);
};

class ChartKitSettings {
private settings: Settings = {
plugins: [],
lang: 'en',
};

get<T extends SettingKey>(key: T) {
return this.settings[key];
}

set(updates: Partial<Settings>) {
const filteredUpdates = removeUndefinedValues(updates);

if (filteredUpdates.lang || filteredUpdates.locale) {
const lang = filteredUpdates.lang || this.get('lang');
const locale = filteredUpdates.locale || this.get('locale');
updateLocale({lang, locale});
}

this.settings = {
...this.settings,
...filteredUpdates,
};
}
}

export const settings = new ChartKitSettings();

settings.set({locale: DEFAULT_LOCALE_SPECIFICATION});
1 change: 1 addition & 0 deletions src/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {YagrPlugin} from './yagr';
29 changes: 29 additions & 0 deletions src/plugins/yagr/__stories__/Yagr.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import {Meta, Story} from '@storybook/react';
import {Button} from '@yandex-cloud/uikit';
import {settings} from '../../../libs';
import {YagrPlugin} from '../../../plugins';
import {ChartKit} from '../../../components/ChartKit';
import {line10} from './mocks/line10';

export default {
title: 'Plugins/Yagr',
component: ChartKit,
} as Meta;

settings.set({plugins: [YagrPlugin]});

const Template: Story<any> = () => {
const [shown, setShown] = React.useState(false);

if (!shown) {
return <Button onClick={() => setShown(true)}>Show chart</Button>;
}

return (
<div style={{height: 300, width: '100%'}}>
<ChartKit id="1" type="yagr" data={line10} />
</div>
);
};
export const Line = Template.bind({});
20 changes: 3 additions & 17 deletions mocks/line10.js → src/plugins/yagr/__stories__/mocks/line10.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const line10 = {
import type {YagrWidgetData} from '../../types';

export const line10: YagrWidgetData = {
data: {
timeline: [
1636838612441, 1636925012441, 1637011412441, 1637097812441, 1637184212441,
Expand Down Expand Up @@ -28,16 +30,6 @@ const line10 = {
},
],
},
timings: {
configResolving: 1,
dataFetching: 1,
jsExecution: 1,
},
sources: {
data: {
program: 'some',
},
},
libraryConfig: {
chart: {
type: 'line',
Expand Down Expand Up @@ -66,17 +58,11 @@ const line10 = {
},
tooltip: {
enabled: true,
total: true,
boundClassName: '.wrapper',
tracking: 'sticky',
className: 'chartkit-theme_common',
},
legend: {},
processing: {},
},
config: {},
params: {},
controls: null,
};

export default line10;
7 changes: 7 additions & 0 deletions src/plugins/yagr/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';
import {ChartKitPlugin} from '../../types';

export const YagrPlugin: ChartKitPlugin = {
type: 'yagr',
renderer: React.lazy(() => import('./renderer/YagrWidget')),
};
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
MinimalValidConfig,
} from 'yagr';

import {YagrWidgetProps} from '../../../types';
import {YagrWidgetProps} from '../types';

import {formatTooltip, TooltipData, TooltipLine} from './tooltip/tooltip';
import {synchronizeTooltipTablesCellsWidth} from './synchronizeTooltipTablesCellsWidth';
Expand Down Expand Up @@ -115,7 +115,7 @@ const getXAxisFormatter =
});
};

export const YagrWidget = (props: YagrWidgetProps) => {
const YagrWidget = (props: YagrWidgetProps) => {
const yagrRef = React.useRef<YagrComponent>(null);

React.useEffect(() => {
Expand Down Expand Up @@ -264,3 +264,5 @@ export const YagrWidget = (props: YagrWidgetProps) => {
/>
);
};

export default YagrWidget;
File renamed without changes.
Loading

0 comments on commit dfb6ed8

Please sign in to comment.