From c2e5be07e4492099cbbed34db91cef61c031f016 Mon Sep 17 00:00:00 2001 From: Artur Yorsh <10753921+artyorsh@users.noreply.github.com> Date: Tue, 14 May 2019 10:03:14 +0300 Subject: [PATCH] docs(theme): add theme components documentation (#387) --- .../applicationProvider.component.tsx | 50 +++++++++- .../theme/style/styleConsumer.component.tsx | 92 ++++++++++++++++++- .../theme/theme/themeConsumer.component.tsx | 73 +++++++++++++-- 3 files changed, 205 insertions(+), 10 deletions(-) diff --git a/src/framework/theme/application/applicationProvider.component.tsx b/src/framework/theme/application/applicationProvider.component.tsx index f61342124..cc63423db 100644 --- a/src/framework/theme/application/applicationProvider.component.tsx +++ b/src/framework/theme/application/applicationProvider.component.tsx @@ -8,9 +8,9 @@ import React from 'react'; import merge from 'lodash.merge'; import { SchemaProcessor } from '@eva/processor-kitten'; import { - ThemeStyleType, - SchemaType, CustomSchemaType, + SchemaType, + ThemeStyleType, } from '@eva/core'; import { StyleProvider } from '../style/styleProvider.component'; import { ThemeProviderProps } from '../theme/themeProvider.component'; @@ -29,6 +29,52 @@ interface State { theme: ThemeType; } +/** + * The `ApplicationProvider` component is designed to be a root of the application. + * + * This does basically two things: + * - Provides styles for react-native-ui-kitten basic components (e.g `Button`); + * - Renders modal window which is used to be common for all elements presented as modal; + * + * @extends React.Component + * + * @property {SchemaType} mapping - Determines the mapping for basic components. + * This is designed to be provided by developers team and can be imported from npm package (e.g `@eva/eva`). + * + * @property {CustomSchemaType} customMapping - Determines the customization mapping. + * This is merged with `mapping` property and designed to be used components customization. + * Optional. + * + * @property {ThemeType} theme - Determines the theme for basic components. + * This is designed to be provided by developers team and can be imported from npm package (e.v `@eva/theme-eva`). + * + * @property {React.ReactNode} children - Determines application root component. + * + * @property ThemeProviderProps + * + * @example ApplicationProvider API example + * + * ``` + * import { mapping } from '@eva/eva'; + * import { theme } from '@eva/theme-eva'; + * import { ApplicationProvider } from '@kitten/theme'; + * import { Application } from './path-to/root.component'; + * + * export default class App extends React.Component { + * + * public render(): React.ReactNode { + * return ( + * + * + * + * ); + * } + * } + * ``` + */ + export class ApplicationProvider extends React.Component { private schemaProcessor: SchemaProcessor = new SchemaProcessor(); diff --git a/src/framework/theme/style/styleConsumer.component.tsx b/src/framework/theme/style/styleConsumer.component.tsx index 41f8be5ab..894632556 100644 --- a/src/framework/theme/style/styleConsumer.component.tsx +++ b/src/framework/theme/style/styleConsumer.component.tsx @@ -38,7 +38,97 @@ export interface ContextProps { export type StyledComponentClass

= React.ComponentClass; -export const styled = (Component: React.ComponentClass

): StyledComponentClass

=> { +/** + * The `styled` function is a High Order Function which is used to apply style `mapping`s on components. + * + * To be styled, source component class should have static `styledComponentName` property which defines + * corresponding component name in `mapping`. (e.g 'Button' for `Button` class). + * + * Passes following props to `Component` when it is rendered: + * + * @property {string} appearance - Determines style appearance of component. Default is provided by mapping. + * @property {ThemeType} theme - Determines theme used to style component. + * @property {StyleType} themedStyle - Determines component style for it's current state. + * @property {(interaction: Interaction[]) => void} - Determines function + * for dispatching current state of component. This is designed to be used as style request function. + * Calls component re-render if style for requested state differ from current. + * + * @param {React.ComponentClass} Component - Determines class of component to be styled. + * + * @example Declaring Styled Component + * + * ``` + * import { + * styled, + * StyledComponentProps, + * Interaction, + * } from '@kitten/theme'; + * + * type StyledButtonProps = ButtonProps & StyledComponentProps; + * + * class Button extends React.Component { + * + * // Define component name used in `mapping` + * static styledComponentName: string = 'Button'; + * + * private onPressIn = (e: GestureResponderEvent) => { + * // Request styles for `active` state and re-render + * + * this.props.dispatch([Interaction.ACTIVE]); + * + * if(this.props.onPressIn) { + * this.props.onPressIn(e); + * } + * }; + * + * private onPressOut = (e: GestureResponderEvent) => { + * // Request styles for default state and re-render + * + * this.props.dispatch([]); + * + * if(this.props.onPressOut) { + * this.props.onPressOut(e); + * } + * }; + * + * public render(): React.ReactElement { + * // Retrieve styles for current state from props (provided with themedStyle prop) + * // And apply it with saving priority of `style` prop + * + * const { style, themedStyle, ...restProps } = this.props; + * + * return ( + * + * ); + * } + * } + * + * export const StyledButton = styled(Button); + * ``` + * + * @example Styled Component Usage + * + * ``` + * import { + * StyledButton, + * StyledButtonProps, + * } from './path-to/styledButton.component'; + * + * public render(): React.ReactElement { + * return ( + * + * ); + * } + * ``` + * + * @returns {StyledComponentClass} - component class which can be used as styled component + */ +export const styled =

(Component: React.ComponentClass

): StyledComponentClass

=> { // @ts-ignore if (!Component.styledComponentName) { diff --git a/src/framework/theme/theme/themeConsumer.component.tsx b/src/framework/theme/theme/themeConsumer.component.tsx index f52625ee9..7779dd348 100644 --- a/src/framework/theme/theme/themeConsumer.component.tsx +++ b/src/framework/theme/theme/themeConsumer.component.tsx @@ -8,9 +8,9 @@ import React from 'react'; import hoistNonReactStatics from 'hoist-non-react-statics'; import { ThemeContext } from './themeContext'; import { - ThemeType, - ThemedStyleType, StyleSheetType, + ThemedStyleType, + ThemeType, } from './type'; interface PrivateProps { @@ -28,12 +28,71 @@ export interface Context { theme: ThemeType; } -// `P` is for component-specific props which could be passed into jsx element -// `T` is for component-specific static props like `TabView.Tab` -export type ThemedComponentClass = React.ComponentClass & T; +export type ThemedComponentClass

= React.ComponentClass; -export const withStyles = (Component: React.ComponentClass

, - createStyles?: CreateStylesFunction): ThemedComponentClass => { +/** + * The `withStyles` function is a High Order Function which is used to create themed style for non-styled component. + * Basically used when need to use `theme` variables somewhere. + * + * Passes following props to `Component` when it is rendered: + * + * @property {ThemeType} theme - Determines theme used to style component. + * @property {StyleType} themedStyle - Determines component style for it's current state. + * + * @param {React.ComponentClass} Component - Determines class of component to be themed + * @param {(theme: ThemeType) => any} createStyles - Determines arrow function used to create styles + * + * @example Declaring Themed Component + * + * ``` + * import { + * withStyles, + * ThemedComponentProps, + * } from '@kitten/theme'; + * + * type ThemedButtonProps = ButtonProps & ThemedComponentProps; + * + * class Button extends React.Component { + * + * public render(): React.ReactElement { + * // Retrieve styles from props (provided with themedStyle prop) + * // And apply it with saving priority of `style` prop + * + * const { style, themedStyle, ...restProps } = this.props; + * + * return ( + * + * ); + * } + * } + * + * export const ThemedButton = withStyles(Button, (theme: ThemeType) => ({ + * backgroundColor: theme['color-primary-500'], + * })); + * ``` + * + * @example Themed Component Usage + * + * ``` + * import { + * ThemedButton, + * ThemedButtonProps, + * } from './path-to/themedButton.component'; + * + * public render(): React.ReactElement { + * return ( + * + * ); + * } + * ``` + * + * @returns {ThemedComponentClass} - component class which can be used as styled component + */ +export const withStyles =

(Component: React.ComponentClass

, + createStyles?: CreateStylesFunction): ThemedComponentClass

=> { type WrappingProps = PrivateProps & WrappedProps; type WrappedProps = ThemedComponentProps & P;