Skip to content

Commit

Permalink
Convert class components that don't have to be class components to fu…
Browse files Browse the repository at this point in the history
…nction components to reduce bundle size
  • Loading branch information
emmatown committed Oct 2, 2019
1 parent fc52085 commit 563b046
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 135 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-terms-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'react-select': patch
---

Convert class components that don't have to be class components to function components to reduce bundle size
141 changes: 70 additions & 71 deletions packages/react-select/src/components/MultiValue.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow
/** @jsx jsx */
import { Component, type Node } from 'react';
import { type Node } from 'react';
import { jsx, ClassNames } from '@emotion/core';
import { CrossIcon } from './indicators';
import type { CommonProps } from '../types';
Expand Down Expand Up @@ -85,91 +85,90 @@ export type MultiValueRemoveProps = {
},
selectProps: any,
};
export class MultiValueRemove extends Component<MultiValueRemoveProps> {
render() {
const { children, innerProps } = this.props;
return <div {...innerProps}>{children || <CrossIcon size={14} />}</div>;
}
export function MultiValueRemove({
children,
innerProps,
}: MultiValueRemoveProps) {
return <div {...innerProps}>{children || <CrossIcon size={14} />}</div>;
}

class MultiValue extends Component<MultiValueProps> {
static defaultProps = {
cropWithEllipsis: true,
};
render() {
const {
children,
className,
components,
cx,
data,
getStyles,
innerProps,
isDisabled,
removeProps,
selectProps,
} = this.props;
const MultiValue = (props: MultiValueProps) => {
const {
children,
className,
components,
cx,
data,
getStyles,
innerProps,
isDisabled,
removeProps,
selectProps,
} = props;

const { Container, Label, Remove } = components;
const { Container, Label, Remove } = components;

return (
<ClassNames>
{({ css, cx: emotionCx }) => (
<Container
return (
<ClassNames>
{({ css, cx: emotionCx }) => (
<Container
data={data}
innerProps={{
...innerProps,
className: emotionCx(
css(getStyles('multiValue', props)),
cx(
{
'multi-value': true,
'multi-value--is-disabled': isDisabled,
},
className
)
),
}}
selectProps={selectProps}
>
<Label
data={data}
innerProps={{
...innerProps,
className: emotionCx(
css(getStyles('multiValue', this.props)),
css(getStyles('multiValueLabel', props)),
cx(
{
'multi-value': true,
'multi-value--is-disabled': isDisabled,
'multi-value__label': true,
},
className
)
),
}}
selectProps={selectProps}
>
<Label
data={data}
innerProps={{
className: emotionCx(
css(getStyles('multiValueLabel', this.props)),
cx(
{
'multi-value__label': true,
},
className
)
),
}}
selectProps={selectProps}
>
{children}
</Label>
<Remove
data={data}
innerProps={{
className: emotionCx(
css(getStyles('multiValueRemove', this.props)),
cx(
{
'multi-value__remove': true,
},
className
)
),
...removeProps,
}}
selectProps={selectProps}
/>
</Container>
)}
</ClassNames>
);
}
}
{children}
</Label>
<Remove
data={data}
innerProps={{
className: emotionCx(
css(getStyles('multiValueRemove', props)),
cx(
{
'multi-value__remove': true,
},
className
)
),
...removeProps,
}}
selectProps={selectProps}
/>
</Container>
)}
</ClassNames>
);
};

MultiValue.defaultProps = {
cropWithEllipsis: true,
};

export default MultiValue;
47 changes: 19 additions & 28 deletions packages/react-select/src/components/containers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow
/** @jsx jsx */
import { Component, type Node } from 'react';
import { type Node } from 'react';
import { jsx } from '@emotion/core';
import type { CommonProps, KeyboardEventHandler } from '../types';

Expand Down Expand Up @@ -79,34 +79,25 @@ export const valueContainerCSS = ({
position: 'relative',
overflow: 'hidden',
});
export class ValueContainer extends Component<ValueContainerProps> {
render() {
const {
children,
className,
cx,
isMulti,
getStyles,
hasValue,
} = this.props;
export const ValueContainer = (props: ValueContainerProps) => {
const { children, className, cx, isMulti, getStyles, hasValue } = props;

return (
<div
css={getStyles('valueContainer', this.props)}
className={cx(
{
'value-container': true,
'value-container--is-multi': isMulti,
'value-container--has-value': hasValue,
},
className
)}
>
{children}
</div>
);
}
}
return (
<div
css={getStyles('valueContainer', props)}
className={cx(
{
'value-container': true,
'value-container--is-multi': isMulti,
'value-container--has-value': hasValue,
},
className
)}
>
{children}
</div>
);
};

// ==============================
// Indicator Container
Expand Down
64 changes: 35 additions & 29 deletions packages/react-select/src/internal/DummyInput.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
// @flow
/** @jsx jsx */
import { Component } from 'react';
import { jsx } from '@emotion/core';

export default class DummyInput extends Component<any> {
render () {
const { in: inProp, out, onExited, appear, enter, exit, innerRef, emotion, ...props } = this.props;
return(
<input
ref={innerRef}
{...props}
css={{
label: 'dummyInput',
// get rid of any default styles
background: 0,
border: 0,
fontSize: 'inherit',
outline: 0,
padding: 0,
// important! without `width` browsers won't allow focus
width: 1,
export default function DummyInput({
in: inProp,
out,
onExited,
appear,
enter,
exit,
innerRef,
emotion,
...props
}: any) {
return (
<input
ref={innerRef}
{...props}
css={{
label: 'dummyInput',
// get rid of any default styles
background: 0,
border: 0,
fontSize: 'inherit',
outline: 0,
padding: 0,
// important! without `width` browsers won't allow focus
width: 1,

// remove cursor on desktop
color: 'transparent',
// remove cursor on desktop
color: 'transparent',

// remove cursor on mobile whilst maintaining "scroll into view" behaviour
left: -100,
opacity: 0,
position: 'relative',
transform: 'scale(0)',
}}
/>
);
}
// remove cursor on mobile whilst maintaining "scroll into view" behaviour
left: -100,
opacity: 0,
position: 'relative',
transform: 'scale(0)',
}}
/>
);
}
12 changes: 5 additions & 7 deletions packages/react-select/src/internal/ScrollCaptor.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class ScrollCaptor extends Component<CaptorProps> {
}
}
stopListening(el: HTMLElement) {

// all the if statements are to appease Flow 😢
if (typeof el.removeEventListener === 'function') {
el.removeEventListener('wheel', this.onWheel, false);
Expand Down Expand Up @@ -134,10 +133,9 @@ type SwitchProps = CaptorProps & {
isEnabled: boolean,
};

export default class ScrollCaptorSwitch extends Component<SwitchProps> {
static defaultProps = { isEnabled: true };
render() {
const { isEnabled, ...props } = this.props;
return isEnabled ? <ScrollCaptor {...props} /> : this.props.children;
}
export default function ScrollCaptorSwitch({
isEnabled = true,
...props
}: SwitchProps) {
return isEnabled ? <ScrollCaptor {...props} /> : props.children;
}

0 comments on commit 563b046

Please sign in to comment.