forked from akveo/react-native-ui-kitten
-
Notifications
You must be signed in to change notification settings - Fork 1
/
applicationProvider.component.tsx
130 lines (117 loc) · 4.31 KB
/
applicationProvider.component.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import React from 'react';
import merge from 'lodash.merge';
import { SchemaProcessor } from '@eva-design/processor';
import {
CustomSchemaType,
SchemaType,
ThemeStyleType,
} from '@eva-design/dss';
import { StyleProvider } from '../style/styleProvider.component';
import { ThemeProviderProps } from '../theme/themeProvider.component';
import { ModalPanel } from '../modal/modalPanel.component';
interface EvaRuntimeProcessingProps {
mapping: SchemaType;
customMapping?: CustomSchemaType;
}
interface EvaBuildtimeProcessingProps {
styles: ThemeStyleType;
}
type EvaProcessingProps = EvaRuntimeProcessingProps | EvaBuildtimeProcessingProps;
export type ApplicationProviderProps = EvaProcessingProps & ThemeProviderProps;
export type ApplicationProviderElement = React.ReactElement<ApplicationProviderProps>;
interface State {
styles: ThemeStyleType;
}
/**
* Overall application container.
*
* @extends React.Component
*
* @property {ReactNode} children - Overall application component.
* Usually, a router or nested providers.
*
* @property {SchemaType} mapping - Mapping for UI Kitten components.
* This is designed to be provided from any `@eva-design/*` package.
* If provided, will be merged with *customMapping* and compiled into styles during the runtime.
* Can be improved with build-time processing with `@ui-kitten/metro-config` package.
*
* @property {CustomSchemaType} customMapping - Customized mapping.
*
* @property {ThemeType} theme - Current theme.
* Designed to be provided from any `@eva-design/*` package.
*
* @property {ThemeStyleType} styles - Styles compiled by bootstrapping Eva packages.
* If provided, will replace runtime styles processing.
* Usually, can be provided by `@ui-kitten/metro-config` package.
*
* @overview-example Simple Usage
* ApplicationProvider is designed to be the root component of the application.
* It should be rendered **once**, to provide Eva styles for nested components.
* ```
* import React from 'react';
* import { ApplicationProvider, Layout, Text } from '@ui-kitten/components';
* import * as eva from '@eva-design/eva';
*
* export default () => (
* <ApplicationProvider {...eva} theme={eva.light}> // <-- {eva.dark} for dark mode
* <Layout style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
* <Text>Welcome to UI Kitten</Text>
* </Layout>
* </ApplicationProvider>
* );
* ```
*
* @overview-example Ecosystem
* Also, it may accept [custom themes](guides/branding) and [icon packages](guides/icon-packages)
* to provide a highly customizable, design system based application.
* ```
* import React from 'react';
* import { ApplicationProvider, IconRegistry, Layout, Text } from '@ui-kitten/components';
* import { EvaIconsPack } from '@ui-kitten/eva-icons';
* import * as eva from '@eva-design/eva';
*
* export default () => (
* <React.Fragment>
* <IconRegistry icons={EvaIconsPack} />
* <ApplicationProvider {...eva} theme={{ ...eva.light, ...myTheme }}>
* <Layout style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
* <Text>Welcome to UI Kitten</Text>
* </Layout>
* </ApplicationProvider>
* </React.Fragment>
* );
* ```
*/
export class ApplicationProvider extends React.Component<ApplicationProviderProps, State> {
public state: State = {
styles: (this.props as EvaBuildtimeProcessingProps).styles,
};
private schemaProcessor: SchemaProcessor = new SchemaProcessor();
constructor(props: ApplicationProviderProps) {
super(props);
if (!this.state.styles) {
const { mapping, customMapping } = this.props as EvaRuntimeProcessingProps;
this.state.styles = this.createStyles(mapping, customMapping);
}
}
private createStyles = (mapping: SchemaType, custom: CustomSchemaType): ThemeStyleType => {
const customizedMapping: SchemaType = merge({}, mapping, custom);
return this.schemaProcessor.process(customizedMapping);
};
public render(): React.ReactNode {
return (
<StyleProvider
theme={this.props.theme}
styles={this.state.styles}>
<ModalPanel>
{this.props.children}
</ModalPanel>
</StyleProvider>
);
}
}