Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: code-completion feature #1737

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/src/articles/guides/code-autocompletion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Code Autocompletion

UI Kitten provides code autocompletion functionality for code editors such as Visual Studio Code, WebStorm, or Sublime Text. The feature provides code suggestions, syntax highlighting, and other code editing aids to help developers write code more efficiently and with fewer errors.
<hr>

## Components

The code completion feature for components is working "out of the box" for predefined mapping types.

![image](assets/images/articles/guides/autocompletion-button-standard.gif)

Also, it is possible to use the code completion feature with user components types added with [custom mapping](design-system/customize-mapping).
To do that, just setup UI Kitten [metro bundler config](guides/improving-performance). After starting metro server, it will parse the file and add new types to declaration.

![image](assets/images/articles/guides/autocompletion-button-custom.gif)

If necessary, you can use the generated types in props definition for your custom components created using UI Kitten. The generated types file is located in `node_modules/@eva-design/eva/mapping.types.ts`

## Theme

It is also possible to use autocompletion with style definitions. In order to get it worked, it is necessary to use [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) typescript feature.
To do that, just create a `ts` file in your project with the merging declaration:

```js
import {ColorValue} from 'react-native/Libraries/StyleSheet/StyleSheet';
import {ThemeColors} from '@eva-design/eva/theme.types';

declare global {
interface ViewStyle {
backgroundColor?: ColorValue | undefined | ThemeColors;
borderColor?: ColorValue | undefined | ThemeColors;
}
}
```
The declaration extends standard react-native interface with `ThemeColors` which is base theme autogenerated type (there are only `backgroundColor` and `borderColor` props are redefined in the example, but you can add additional props if needed).
If you have your own theme, it is possible to add your keys into that `ThemeColors` type either. It can be done with the [metro bundler config customization](guides/improving-performance) feature already used in the case above. The only additional step is adding path to your theme to appropriate `EvaConfig` property:

```js
const evaConfig = {
evaPackage: '@eva-design/eva',
customMappingPath: './myMapping.json',
customThemePath: './myTheme.json',
};
```
After starting metro, it will regenerate `ThemeColors` type by adding your theme values.

![image](assets/images/articles/guides/autocompletion-stylesheet.gif)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions docs/src/structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ export const structure = [
description: 'How to get rid of performance issues in UI Kitten when using mapping customization or React Native Navigation by Wix',
keywords: 'ui kitten, react native apps, custom mapping path, evaConfig, evaPackage',
},
{
type: 'page',
name: 'Code Autocompletion',
children: [
{
type: 'block',
block: 'markdown',
source: 'guides/code-autocompletion.md',
},
],
title: 'Code Autocompletion',
description: 'How to use code autocompletion feature with UI Kitten',
keywords: 'ui kitten, react native apps, custom mapping path, evaConfig, evaPackage, code autocompletion',
},
],
},
{
Expand Down
27 changes: 15 additions & 12 deletions src/components/ui/avatar/avatar.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,20 @@ import {
ImageStyle,
StyleSheet,
} from 'react-native';
import {
EvaSize,
Overwrite,
LiteralUnion,
} from '../../devsupport';
import {
styled,
StyledComponentProps,
StyleType,
} from '../../theme';
import { AvatarAppearance, AvatarShape, AvatarSize } from '@eva-design/eva/mapping.types';

type AvatarStyledProps = Overwrite<StyledComponentProps, {
appearance?: LiteralUnion<'default'>;
}>;
interface AvatarStyledProps extends StyledComponentProps {
appearance?: AvatarAppearance;
}

export type AvatarProps<P = ImageProps> = AvatarStyledProps & P & {
shape?: 'round' | 'rounded' | 'square' | string;
size?: EvaSize;
shape?: AvatarShape;
size?: AvatarSize;
/**
* We use `any` here to prevent ts complains for most of the libraries that use
* React.ComponentType & SomeType to describe static / instance methods for the components.
Expand All @@ -44,12 +40,19 @@ export type AvatarElement = React.ReactElement<AvatarProps>;
*
* @extends React.Component
*
* @property {string} appearance - Appearance of the component.
* The predefined one is `default`.
* Can be extended with custom mapping feature.
* Defaults to *default*.
*
* @property {string} shape - Shape of the component.
* Can be `round`, `rounded` or `square`.
* The predefined ones are `round`, `rounded` or `square`.
* Can be extended with custom mapping feature.
* Defaults to *round*.
*
* @property {string} size - Size of the component.
* Can be `tiny`, `small`, `medium`, `large`, or `giant`.
* The predefined ones are `tiny`, `small`, `medium`, `large`, or `giant`.
* Can be extended with custom mapping feature.
* Defaults to *medium*.
*
* @property {React.ComponentType} ImageComponent - A component to render.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import {
} from 'react-native';
import {
ChildrenWithProps,
Overwrite,
LiteralUnion,
} from '../../devsupport';
import {
styled,
Expand All @@ -30,10 +28,11 @@ import {
TabIndicator,
TabIndicatorElement,
} from '../shared/tabIndicator.component';
import { BottomNavigationAppearance } from '@eva-design/eva/mapping.types';

type BottomNavigationStyledProps = Overwrite<StyledComponentProps, {
appearance?: LiteralUnion<'default' | 'noIndicator'>;
}>;
interface BottomNavigationStyledProps extends StyledComponentProps {
appearance?: BottomNavigationAppearance;
}

export interface BottomNavigationProps extends ViewProps, BottomNavigationStyledProps {
children?: ChildrenWithProps<BottomNavigationTabProps>;
Expand All @@ -57,7 +56,7 @@ export type BottomNavigationElement = React.ReactElement<BottomNavigationProps>;
* @property {(number) => void} onSelect - Called when tab is pressed.
*
* @property {string} appearance - Appearance of the component.
* Can be `default` or `noIndicator`.
* The predefined ones are `default` or `noIndicator`. Can be extended with custom mapping feature.
*
* @property {StyleProp<ViewStyle>} indicatorStyle - Styles of the indicator.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import {
TouchableWeb,
TouchableWebElement,
TouchableWebProps,
Overwrite,
LiteralUnion,
} from '../../devsupport';
import {
Interaction,
Expand All @@ -28,10 +26,11 @@ import {
StyleType,
} from '../../theme';
import { TextProps } from '../text/text.component';
import { BottomNavigationTabAppearance } from '@eva-design/eva/mapping.types';

type BottomNavigationTabStyledProps = Overwrite<StyledComponentProps, {
appearance?: LiteralUnion<'default' | string>;
}>;
interface BottomNavigationTabStyledProps extends StyledComponentProps {
appearance?: BottomNavigationTabAppearance;
}

export interface BottomNavigationTabProps extends TouchableWebProps, BottomNavigationTabStyledProps {
title?: RenderProp<TextProps> | React.ReactText;
Expand Down
26 changes: 13 additions & 13 deletions src/components/ui/button/button.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ import {
TargetedEvent,
} from 'react-native';
import {
EvaSize,
EvaStatus,
FalsyFC,
FalsyText,
RenderProp,
TouchableWeb,
TouchableWebElement,
TouchableWebProps,
Overwrite,
LiteralUnion,
} from '../../devsupport';
import {
Interaction,
Expand All @@ -31,19 +27,20 @@ import {
StyleType,
} from '../../theme';
import { TextProps } from '../text/text.component';
import { ButtonAppearance, ButtonSize, ButtonStatus } from '@eva-design/eva/mapping.types';

type ButtonStyledProps = Overwrite<StyledComponentProps, {
appearance?: LiteralUnion<'filled' | 'outline' | 'ghost'>;
}>;
interface ButtonStyledProps extends StyledComponentProps {
appearance?: ButtonAppearance;
}

type TouchableWebPropsWithoutChildren = Omit<TouchableWebProps, 'children'>;

export interface ButtonProps extends TouchableWebPropsWithoutChildren, ButtonStyledProps {
children?: RenderProp<TextProps> | React.ReactText;
accessoryLeft?: RenderProp<Partial<ImageProps>>;
accessoryRight?: RenderProp<Partial<ImageProps>>;
status?: EvaStatus;
size?: EvaSize;
status?: ButtonStatus;
size?: ButtonSize;
}

export type ButtonElement = React.ReactElement<ButtonProps>;
Expand All @@ -66,16 +63,19 @@ export type ButtonElement = React.ReactElement<ButtonProps>;
* Expected to return an Image.
*
* @property {string} appearance - Appearance of the component.
* Can be `filled`, `outline` or `ghost`.
* The predefined ones are `filled`, `outline` or `ghost`.
* Can be extended with custom mapping feature.
* Defaults to *filled*.
*
* @property {string} status - Status of the component.
* Can be `basic`, `primary`, `success`, `info`, `warning`, `danger` or `control`.
* The predefined ones are `basic`, `primary`, `success`, `info`, `warning`, `danger` or `control`.
* Can be extended with custom mapping feature.
* Defaults to *primary*.
* Use *control* status when needed to display within a contrast container.
*
* @property {string} size - Size of the component.
* Can be `tiny`, `small`, `medium`, `large`, or `giant`.
* The predefined ones are `tiny`, `small`, `medium`, `large`, or `giant`.
* Can be extended with custom mapping feature.
* Defaults to *medium*.
*
* @property {TouchableOpacityProps} ...TouchableOpacityProps - Any props applied to TouchableOpacity component.
Expand All @@ -87,7 +87,7 @@ export type ButtonElement = React.ReactElement<ButtonProps>;
* Button can be disabled with `disabled` property.
*
* @overview-example ButtonAppearances
* Within Eva Design System, it can be `filled`, `outline` or `ghost`.
* The predefined appearances are `filled`, `outline` or `ghost`.
*
* @overview-example ButtonAccessories
* Also, it may contain inner views configured with `accessoryLeft` and `accessoryRight` properties.
Expand Down
15 changes: 6 additions & 9 deletions src/components/ui/buttonGroup/buttonGroup.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import {
} from 'react-native';
import {
ChildrenWithProps,
EvaSize,
EvaStatus,
Overwrite,
LiteralUnion,
} from '../../devsupport';
import {
styled,
Expand All @@ -27,15 +23,16 @@ import {
ButtonElement,
ButtonProps,
} from '../button/button.component';
import { ButtonGroupAppearance, ButtonGroupSize, ButtonGroupStatus } from '@eva-design/eva/mapping.types';

type ButtonGroupStyledProps = Overwrite<StyledComponentProps, {
appearance?: LiteralUnion<'filled' | 'outline' | 'ghost'>;
}>;
interface ButtonGroupStyledProps extends StyledComponentProps {
appearance?: ButtonGroupAppearance;
}

export interface ButtonGroupProps extends ViewProps, ButtonGroupStyledProps {
children: ChildrenWithProps<ButtonProps>;
status?: EvaStatus;
size?: EvaSize;
status?: ButtonGroupStatus;
size?: ButtonGroupSize;
}

export type ButtonGroupElement = React.ReactElement<ButtonGroupProps>;
Expand Down
17 changes: 8 additions & 9 deletions src/components/ui/card/card.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@ import {
ViewProps,
} from 'react-native';
import {
EvaStatus,
FalsyFC,
RenderProp,
TouchableWeb,
TouchableWebElement,
TouchableWebProps,
Overwrite,
LiteralUnion,
} from '../../devsupport';
import {
Interaction,
Expand All @@ -28,17 +25,18 @@ import {
StyleType,
} from '../../theme';
import { Divider } from '../divider/divider.component';
import { CardAppearance, CardStatus } from '@eva-design/eva/mapping.types';

type CardStyledProps = Overwrite<StyledComponentProps, {
appearance?: LiteralUnion<'filled' | 'outline'>;
}>;
interface CardStyledProps extends StyledComponentProps {
appearance?: CardAppearance;
}

export interface CardProps extends TouchableWebProps, CardStyledProps {
children?: React.ReactNode;
header?: RenderProp<ViewProps>;
footer?: RenderProp<ViewProps>;
accent?: RenderProp<ViewProps>;
status?: EvaStatus;
status?: CardStatus;
}

export type CardElement = React.ReactElement<CardProps>;
Expand All @@ -61,11 +59,12 @@ export type CardElement = React.ReactElement<CardProps>;
* Accents may change it's color depending on *status* property.
*
* @property {string} appearance - Appearance of the component.
* Can be `filled` or `outline`.
* The predefined ones are `filled` or `outline`. Can be extended with custom mapping feature.
* Defaults to *outline*.
*
* @property {string} status - Status of the component.
* Can be `basic`, `primary`, `success`, `info`, `warning`, `danger` or `control`.
* The predefined ones are `basic`, `primary`, `success`, `info`, `warning`, `danger` or `control`.
* Can be extended with custom mapping feature.
* Defaults to *basic*.
*
* @property {TouchableOpacityProps} ...TouchableOpacityProps - Any props applied to TouchableOpacity component.
Expand Down
16 changes: 7 additions & 9 deletions src/components/ui/checkbox/checkbox.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ import {
View,
} from 'react-native';
import {
EvaStatus,
FalsyText,
RenderProp,
TouchableWeb,
TouchableWebElement,
TouchableWebProps,
Overwrite,
LiteralUnion,
} from '../../devsupport';
import {
Interaction,
Expand All @@ -38,10 +35,11 @@ import {
Minus,
MinusProps,
} from '../shared/minus.component';
import { CheckBoxAppearance, CheckBoxStatus } from '@eva-design/eva/mapping.types';

type CheckBoxStyledProps = Overwrite<StyledComponentProps, {
appearance?: LiteralUnion<'default' | string>;
}>;
interface CheckBoxStyledProps extends StyledComponentProps {
appearance?: CheckBoxAppearance;
}

type TouchableWebPropsWithoutChildren = Omit<TouchableWebProps, 'children'>;

Expand All @@ -50,7 +48,7 @@ export interface CheckBoxProps extends TouchableWebPropsWithoutChildren, CheckBo
checked?: boolean;
onChange?: (checked: boolean, indeterminate: boolean) => void;
indeterminate?: boolean;
status?: EvaStatus;
status?: CheckBoxStatus;
}

export type CheckBoxElement = React.ReactElement<CheckBoxProps>;
Expand All @@ -77,8 +75,8 @@ export type CheckBoxElement = React.ReactElement<CheckBoxProps>;
* If it is a function, expected to return a Text.
*
* @property {string} status - Status of the component.
* Can be `basic`, `primary`, `success`, `info`, `warning`, `danger` or `control`.
* Defaults to *basic*.
* The predefined ones are `basic`, `primary`, `success`, `info`, `warning`, `danger` or `control`.
* Can be extended with custom mapping feature. Defaults to *basic*.
* Use *control* status when needed to display within a contrast container.
*
* @property {TouchableOpacityProps} ...TouchableOpacityProps - Any props applied to TouchableOpacity component.
Expand Down
Loading