Skip to content

Commit

Permalink
Merge 8bc4abd into 1d7a341
Browse files Browse the repository at this point in the history
  • Loading branch information
32penkin committed Oct 17, 2019
2 parents 1d7a341 + 8bc4abd commit 09f6066
Show file tree
Hide file tree
Showing 16 changed files with 1,231 additions and 276 deletions.
1 change: 1 addition & 0 deletions src/framework/ui/index.ts
Expand Up @@ -69,6 +69,7 @@ export {
SelectProps,
SelectElement,
SelectOption,
KeyExtractorType,
} from './select/select.component';
export { SelectOptionType } from './select/selectOption.component';
export {
Expand Down
16 changes: 16 additions & 0 deletions src/framework/ui/radio/radio.spec.tsx.snap
Expand Up @@ -138,6 +138,7 @@ exports[`@radio: matches snapshot default 1`] = `
"color-basic-default": "$color-basic-200",
"color-basic-disabled": "$color-basic-300",
"color-basic-focus": "$color-basic-500",
"color-basic-hover": "$color-basic-200",
"color-basic-transparent-100": "rgba(143, 155, 179, 0.08)",
"color-basic-transparent-200": "rgba(143, 155, 179, 0.16)",
"color-basic-transparent-300": "rgba(143, 155, 179, 0.24)",
Expand All @@ -157,6 +158,7 @@ exports[`@radio: matches snapshot default 1`] = `
"color-danger-default": "$color-danger-500",
"color-danger-disabled": "$color-danger-300",
"color-danger-focus": "$color-danger-700",
"color-danger-hover": "$color-danger-400",
"color-danger-transparent-100": "rgba(255, 61, 113, 0.08)",
"color-danger-transparent-200": "rgba(255, 61, 113, 0.16)",
"color-danger-transparent-300": "rgba(255, 61, 113, 0.24)",
Expand All @@ -176,6 +178,7 @@ exports[`@radio: matches snapshot default 1`] = `
"color-info-default": "$color-info-500",
"color-info-disabled": "$color-info-300",
"color-info-focus": "$color-info-700",
"color-info-hover": "$color-info-400",
"color-info-transparent-100": "rgba(0, 149, 255, 0.08)",
"color-info-transparent-200": "rgba(0, 149, 255, 0.16)",
"color-info-transparent-300": "rgba(0, 149, 255, 0.24)",
Expand All @@ -195,6 +198,7 @@ exports[`@radio: matches snapshot default 1`] = `
"color-primary-default": "$color-primary-500",
"color-primary-disabled": "$color-primary-200",
"color-primary-focus": "$color-primary-700",
"color-primary-hover": "$color-primary-400",
"color-primary-transparent-100": "rgba(51, 102, 255, 0.08)",
"color-primary-transparent-200": "rgba(51, 102, 255, 0.16)",
"color-primary-transparent-300": "rgba(51, 102, 255, 0.24)",
Expand Down Expand Up @@ -223,6 +227,7 @@ exports[`@radio: matches snapshot default 1`] = `
"color-success-default": "$color-success-500",
"color-success-disabled": "$color-success-200",
"color-success-focus": "$color-success-700",
"color-success-hover": "$color-success-400",
"color-success-transparent-100": "rgba(0, 224, 150, 0.08)",
"color-success-transparent-200": "rgba(0, 224, 150, 0.16)",
"color-success-transparent-300": "rgba(0, 224, 150, 0.24)",
Expand Down Expand Up @@ -251,6 +256,7 @@ exports[`@radio: matches snapshot default 1`] = `
"color-warning-default": "$color-warning-500",
"color-warning-disabled": "$color-warning-300",
"color-warning-focus": "$color-warning-700",
"color-warning-hover": "$color-warning-400",
"color-warning-transparent-100": "rgba(255, 170, 0, 0.08)",
"color-warning-transparent-200": "rgba(255, 170, 0, 0.16)",
"color-warning-transparent-300": "rgba(255, 170, 0, 0.24)",
Expand All @@ -269,20 +275,30 @@ exports[`@radio: matches snapshot default 1`] = `
"text-danger-active-color": "$color-danger-active",
"text-danger-color": "$color-danger-default",
"text-danger-disabled-color": "$color-danger-disabled",
"text-danger-focus-color": "$color-danger-focus",
"text-danger-hover-color": "$color-danger-hover",
"text-disabled-color": "$color-basic-500",
"text-hint-color": "$color-basic-600",
"text-info-active-color": "$color-info-active",
"text-info-color": "$color-info-default",
"text-info-disabled-color": "$color-info-disabled",
"text-info-focus-color": "$color-info-focus",
"text-info-hover-color": "$color-info-hover",
"text-primary-active-color": "$color-primary-active",
"text-primary-color": "$color-primary-default",
"text-primary-disabled-color": "$color-primary-disabled",
"text-primary-focus-color": "$color-primary-focus",
"text-primary-hover-color": "$color-primary-hover",
"text-success-active-color": "$color-success-active",
"text-success-color": "$color-success-default",
"text-success-disabled-color": "$color-success-disabled",
"text-success-focus-color": "$color-success-focus",
"text-success-hover-color": "$color-success-hover",
"text-warning-active-color": "$color-warning-active",
"text-warning-color": "$color-warning-default",
"text-warning-disabled-color": "$color-warning-disabled",
"text-warning-focus-color": "$color-warning-focus",
"text-warning-hover-color": "$color-warning-hover",
}
}
>
Expand Down
22 changes: 17 additions & 5 deletions src/framework/ui/select/select.component.tsx
Expand Up @@ -57,6 +57,7 @@ type IconProp = (style: ImageStyle, visible: boolean) => IconElement;
type SelectChildren = [SelectOptionsListElement, TextElement, ControlElement];

export type SelectOption = Array<SelectOptionType> | SelectOptionType;
export type KeyExtractorType = (item: SelectOptionType) => string;

const MEASURED_CONTROL_TAG: string = 'Control';

Expand All @@ -74,6 +75,7 @@ interface ComponentProps {
onSelect: (option: SelectOption, event?: GestureResponderEvent) => void;
status?: string;
renderItem?: (item: ListRenderItemInfo<SelectOptionType>) => React.ReactElement<any>;
keyExtractor?: KeyExtractorType;
}

export type SelectProps = StyledComponentProps & TouchableOpacityProps & ComponentProps;
Expand All @@ -85,7 +87,9 @@ interface State {
}

/**
* Styled `Select` component.
* Styled `Select` component. By default, the MultiSelect compares the items by reference.
* To specify a field from the data object which will be used for the comparison,
* implement the `keyExtractor` property.
*
* @extends React.Component
*
Expand Down Expand Up @@ -125,6 +129,8 @@ interface State {
*
* @property {StyleProp<TextStyle>} textStyle - Customizes text style.
*
* @property {KeyExtractorType} keyExtractor - Used to extract a unique key for a given item;
*
* @property TouchableOpacityProps
*
* @property StyledComponentProps
Expand All @@ -137,6 +143,10 @@ interface State {
*
* @overview-example SelectWithGroups
*
* @overview-example SelectMultiPreselectedInline
*
* @overview-example SelectMultiPreselectedReference
*
* @example SelectCustomIcon
*
* @example SelectInlineStyling
Expand All @@ -154,7 +164,7 @@ class SelectComponent extends React.Component<SelectProps, State> {
optionsListWidth: 0,
};

private strategy: SelectionStrategy;
private strategy: SelectionStrategy<SelectOption>;
private iconAnimation: Animated.Value;

constructor(props: SelectProps) {
Expand Down Expand Up @@ -202,10 +212,12 @@ class SelectComponent extends React.Component<SelectProps, State> {
this.setState({ optionsListWidth: width });
};

private createSelectionStrategy = (): SelectionStrategy => {
const { multiSelect, selectedOption } = this.props;
private createSelectionStrategy = (): SelectionStrategy<SelectOption> => {
const { multiSelect, selectedOption, keyExtractor, data } = this.props;

return multiSelect ? new MultiSelectStrategy(selectedOption) : new SingleSelectStrategy(selectedOption);
return multiSelect ?
new MultiSelectStrategy(selectedOption, data, keyExtractor) :
new SingleSelectStrategy(selectedOption, data, keyExtractor);
};

private setVisibility = (): void => {
Expand Down
81 changes: 77 additions & 4 deletions src/framework/ui/select/select.spec.tsx
Expand Up @@ -57,11 +57,16 @@ interface Props {
labelStyle?: StyleType;
placeholderStyle?: StyleType;
controlStyle?: StyleType;
preselectedRef?: SelectOption;
preselectedInline?: SelectOption;
preselectedMultiRef?: SelectOption;
preselectedMultiInline?: SelectOption;
onSelectPress?: () => void;
onSelectPressIn?: () => void;
onSelectPressOut?: () => void;
onSelectLongPress?: () => void;
onMultiSelectPress?: () => void;
keyExtractor?: (item: SelectOptionType) => string;
}

interface State {
Expand All @@ -71,9 +76,33 @@ interface State {

class TestApplication extends React.Component<Props, State> {

private getSelectedOption = (): SelectOption => {
const { preselectedRef, preselectedInline } = this.props;

if (preselectedInline) {
return preselectedInline;
} else if (preselectedRef) {
return preselectedRef;
} else {
return null;
}
};

private getSelectedOptionMulti = (): SelectOption => {
const { preselectedMultiInline, preselectedMultiRef } = this.props;

if (preselectedMultiInline) {
return preselectedMultiInline;
} else if (preselectedMultiRef) {
return preselectedMultiRef;
} else {
return [];
}
};

public state: State = {
selectSelected: null,
selectMultiSelected: [],
selectSelected: this.getSelectedOption(),
selectMultiSelected: this.getSelectedOptionMulti(),
};

private onSelectSelect = (selectSelected: SelectOption): void => {
Expand Down Expand Up @@ -106,7 +135,7 @@ class TestApplication extends React.Component<Props, State> {
onSelectPressIn,
onSelectPressOut,
onSelectLongPress,

keyExtractor,
} = this.props;

return (
Expand All @@ -123,6 +152,7 @@ class TestApplication extends React.Component<Props, State> {
onPressOut={onSelectPressOut}
onLongPress={onSelectLongPress}
onSelect={this.onSelectSelect}
keyExtractor={keyExtractor}
/>
<Select
disabled={multiSelectDisabled}
Expand All @@ -134,11 +164,11 @@ class TestApplication extends React.Component<Props, State> {
icon={this.renderIcon}
onPress={onMultiSelectPress}
onSelect={this.onSelectMultiSelect}
keyExtractor={keyExtractor}
/>
</ApplicationProvider>
);
}

}


Expand Down Expand Up @@ -285,4 +315,47 @@ describe('@ select component checks', () => {
expect(placeholder).toBe(passedPlaceholder);
});

it('* preselected item by reference objects equality checks', () => {
const preselectedDefault: SelectOption = data[3];
const preselectedMulti: SelectOption = [data[3], data[4]];
const application: RenderAPI = render(
<TestApplication
preselectedRef={preselectedDefault}
preselectedMultiRef={preselectedMulti}
/>,
);

const { selectedOption: defaultSelect } = application.getAllByType(TouchableOpacity)[0].props;
const { selectedOption: multiSelect } = application.getAllByType(TouchableOpacity)[1].props;

expect(defaultSelect).toEqual(preselectedDefault);
expect(multiSelect).toEqual(preselectedMulti);
});

it('* preselected item inline objects equality checks', () => {
const preselectedMulti: SelectOption = [{ text: 'Option 4' }, { text: 'Option 6' }];
const application: RenderAPI = render(
<TestApplication
preselectedMultiInline={preselectedMulti}
keyExtractor={(item: SelectOptionType) => item.text}
/>,
);

fireEvent.press(application.getAllByType(TouchableOpacity)[1]);
fireEvent(application.getAllByType(CheckBox)[6], 'onChange');

const { selectedOption: multiSelect } = application.getAllByType(TouchableOpacity)[1].props;

expect(multiSelect.length).toBe(1);
expect(stringify(multiSelect)).toBe(stringify([{ text: 'Option 6' }]));
});

it('* unexpected preselected', () => {
const preselectedDefault: SelectOption = { text: 'Option 4545'};

expect(() => {
render(<TestApplication preselectedInline={preselectedDefault}/>);
}).toThrowError();
});

});
3 changes: 2 additions & 1 deletion src/framework/ui/select/selectGroupOption.component.tsx
Expand Up @@ -20,11 +20,12 @@ import {
SelectOptionProps,
SelectOptionType,
} from './selectOption.component';
import { SelectOption as SelectOptionProp} from './select.component';
import { SelectionStrategy } from './selection.strategy';

interface ComponentProps {
multiSelect?: boolean;
strategy: SelectionStrategy;
strategy: SelectionStrategy<SelectOptionProp>;
renderItem?: (item: ListRenderItemInfo<SelectOptionType>) => React.ReactElement<any>;
}

Expand Down
8 changes: 4 additions & 4 deletions src/framework/ui/select/selectOption.component.tsx
Expand Up @@ -89,8 +89,6 @@ class SelectOptionComponent extends React.Component<SelectOptionProps> {
textFontWeight,
textLineHeight,
textMarginHorizontal,
multiSelectBackgroundColor,
multiSelectTextColor,
...containerStyles
} = source;

Expand Down Expand Up @@ -124,7 +122,6 @@ class SelectOptionComponent extends React.Component<SelectOptionProps> {
<TouchableOpacity
activeOpacity={1.0}
{...restProps}
disabled={item.disabled}
style={[styles.container, container, style]}
onPress={this.onPress}
onPressIn={this.onPressIn}
Expand All @@ -145,7 +142,7 @@ class SelectOptionComponent extends React.Component<SelectOptionProps> {
style={[styles.container, container, style]}>
<CheckBox
text={item.text}
textStyle={[text, item.textStyle]}
textStyle={[text, item.textStyle, styles.multiSelectText]}
disabled={disabled}
checked={selected}
indeterminate={indeterminate}
Expand All @@ -167,6 +164,9 @@ const styles = StyleSheet.create({
},
icon: {},
text: {},
multiSelectText: {
width: '100%',
},
});

export const SelectOption = styled<SelectOptionProps>(SelectOptionComponent);
3 changes: 2 additions & 1 deletion src/framework/ui/select/selectOptionsList.component.tsx
Expand Up @@ -23,6 +23,7 @@ import {
SelectGroupOption,
SelectGroupOptionElement,
} from './selectGroupOption.component';
import { SelectOption as SelectOptionProp} from './select.component';
import { SelectionStrategy } from './selection.strategy';

type DefaultMenuItemElement = SelectOptionElement | SelectGroupOptionElement;
Expand All @@ -31,7 +32,7 @@ type MenuItemElement = DefaultMenuItemElement | React.ReactElement<any>;
export interface ComponentProps {
data: SelectOptionType[];
multiSelect?: boolean;
strategy: SelectionStrategy;
strategy: SelectionStrategy<SelectOptionProp>;
renderItem?: (item: ListRenderItemInfo<SelectOptionType>) => React.ReactElement<any>;
onSelect: (option: SelectOptionType, event?: GestureResponderEvent) => void;
}
Expand Down

0 comments on commit 09f6066

Please sign in to comment.