diff options
author | muhamedsalih-tw <104364298+muhamedsalih-tw@users.noreply.github.com> | 2022-10-27 07:13:47 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-27 01:43:47 +0000 |
commit | 81c43ecc3d17e0dbf7ad1d949b6d977f2c65bd48 (patch) | |
tree | dfa7c08cb54fb81b7d2e788d350de52c2ebd05d2 /src/components | |
parent | 6.2.1-nightly.30 [skip ci] (diff) | |
download | ferdium-app-81c43ecc3d17e0dbf7ad1d949b6d977f2c65bd48.tar.gz ferdium-app-81c43ecc3d17e0dbf7ad1d949b6d977f2c65bd48.tar.zst ferdium-app-81c43ecc3d17e0dbf7ad1d949b6d977f2c65bd48.zip |
fix: 'failed prop' warning in QuickSwitchModal, SettingsNavigation, SettingsWindow and Recipe component tree (#713)
* chore: turn off eslint rule @typescript-eslint/no-useless-constructor to initialize dynamic props & state
Co-authored-by: Muhamed <>
Co-authored-by: Vijay A <vraravam@users.noreply.github.com>
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/settings/navigation/SettingsNavigation.tsx (renamed from src/components/settings/navigation/SettingsNavigation.jsx) | 70 | ||||
-rw-r--r-- | src/components/settings/recipes/RecipeItem.tsx (renamed from src/components/settings/recipes/RecipeItem.js) | 23 | ||||
-rw-r--r-- | src/components/settings/recipes/RecipesDashboard.tsx (renamed from src/components/settings/recipes/RecipesDashboard.jsx) | 65 | ||||
-rw-r--r-- | src/components/ui/SearchInput.tsx | 89 | ||||
-rw-r--r-- | src/components/ui/effects/Appear.tsx | 14 |
5 files changed, 121 insertions, 140 deletions
diff --git a/src/components/settings/navigation/SettingsNavigation.jsx b/src/components/settings/navigation/SettingsNavigation.tsx index e1242a7fe..95c69027c 100644 --- a/src/components/settings/navigation/SettingsNavigation.jsx +++ b/src/components/settings/navigation/SettingsNavigation.tsx | |||
@@ -1,18 +1,13 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
3 | import { defineMessages, injectIntl } from 'react-intl'; | ||
4 | import { inject, observer } from 'mobx-react'; | 3 | import { inject, observer } from 'mobx-react'; |
5 | import { RouterStore } from '@superwf/mobx-react-router'; | ||
6 | |||
7 | import { NavLink } from 'react-router-dom'; | 4 | import { NavLink } from 'react-router-dom'; |
5 | import { StoresProps } from '../../../@types/ferdium-components.types'; | ||
8 | import { | 6 | import { |
9 | LOCAL_SERVER, | 7 | LOCAL_SERVER, |
10 | LIVE_FERDIUM_API, | 8 | LIVE_FERDIUM_API, |
11 | LIVE_FRANZ_API, | 9 | LIVE_FRANZ_API, |
12 | } from '../../../config'; | 10 | } from '../../../config'; |
13 | import UIStore from '../../../stores/UIStore'; | ||
14 | import SettingsStore from '../../../stores/SettingsStore'; | ||
15 | import UserStore from '../../../stores/UserStore'; | ||
16 | import globalMessages from '../../../i18n/globalMessages'; | 11 | import globalMessages from '../../../i18n/globalMessages'; |
17 | 12 | ||
18 | const messages = defineMessages({ | 13 | const messages = defineMessages({ |
@@ -50,40 +45,37 @@ const messages = defineMessages({ | |||
50 | }, | 45 | }, |
51 | }); | 46 | }); |
52 | 47 | ||
53 | class SettingsNavigation extends Component { | 48 | interface IProps extends Partial<StoresProps>, WrappedComponentProps { |
54 | static propTypes = { | 49 | serviceCount: number; |
55 | stores: PropTypes.shape({ | 50 | workspaceCount: number; |
56 | ui: PropTypes.instanceOf(UIStore).isRequired, | 51 | } |
57 | user: PropTypes.instanceOf(UserStore).isRequired, | 52 | |
58 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | 53 | @inject('stores', 'actions') |
59 | router: PropTypes.instanceOf(RouterStore).isRequired, | 54 | @observer |
60 | }).isRequired, | 55 | class SettingsNavigation extends Component<IProps> { |
61 | actions: PropTypes.shape({ | 56 | constructor(props: IProps) { |
62 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | 57 | super(props); |
63 | }).isRequired, | 58 | } |
64 | serviceCount: PropTypes.number.isRequired, | ||
65 | workspaceCount: PropTypes.number.isRequired, | ||
66 | }; | ||
67 | 59 | ||
68 | handleLogout() { | 60 | handleLogout(): void { |
69 | const isUsingWithoutAccount = | 61 | const isUsingWithoutAccount = |
70 | this.props.stores.settings.app.server === LOCAL_SERVER; | 62 | this.props.stores!.settings.app.server === LOCAL_SERVER; |
71 | 63 | ||
72 | // Remove current auth token | 64 | // Remove current auth token |
73 | localStorage.removeItem('authToken'); | 65 | localStorage.removeItem('authToken'); |
74 | 66 | ||
75 | if (isUsingWithoutAccount) { | 67 | if (isUsingWithoutAccount) { |
76 | // Reset server back to Ferdium API | 68 | // Reset server back to Ferdium API |
77 | this.props.actions.settings.update({ | 69 | this.props.actions!.settings.update({ |
78 | type: 'app', | 70 | type: 'app', |
79 | data: { | 71 | data: { |
80 | server: LIVE_FERDIUM_API, | 72 | server: LIVE_FERDIUM_API, |
81 | }, | 73 | }, |
82 | }); | 74 | }); |
83 | } | 75 | } |
84 | this.props.stores.user.isLoggingOut = true; | 76 | this.props.stores!.user.isLoggingOut = true; |
85 | 77 | ||
86 | this.props.stores.router.push('/auth/welcome'); | 78 | this.props.stores!.router.push('/auth/welcome'); |
87 | 79 | ||
88 | // Reload Ferdium, otherwise many settings won't sync correctly with the server | 80 | // Reload Ferdium, otherwise many settings won't sync correctly with the server |
89 | // after logging into another account | 81 | // after logging into another account |
@@ -91,10 +83,9 @@ class SettingsNavigation extends Component { | |||
91 | } | 83 | } |
92 | 84 | ||
93 | render() { | 85 | render() { |
94 | const { serviceCount, workspaceCount, stores } = this.props; | 86 | const { serviceCount, workspaceCount, stores, intl } = this.props; |
95 | const { intl } = this.props; | 87 | const isUsingWithoutAccount = stores!.settings.app.server === LOCAL_SERVER; |
96 | const isUsingWithoutAccount = stores.settings.app.server === LOCAL_SERVER; | 88 | const isUsingFranzServer = stores!.settings.app.server === LIVE_FRANZ_API; |
97 | const isUsingFranzServer = stores.settings.app.server === LIVE_FRANZ_API; | ||
98 | 89 | ||
99 | return ( | 90 | return ( |
100 | <div className="settings-navigation"> | 91 | <div className="settings-navigation"> |
@@ -163,12 +154,12 @@ class SettingsNavigation extends Component { | |||
163 | } | 154 | } |
164 | > | 155 | > |
165 | {intl.formatMessage(globalMessages.settings)} | 156 | {intl.formatMessage(globalMessages.settings)} |
166 | {stores.settings.app.automaticUpdates && | 157 | {stores!.settings.app.automaticUpdates && |
167 | (stores.ui.showServicesUpdatedInfoBar || | 158 | (stores!.ui.showServicesUpdatedInfoBar || |
168 | stores.app.updateStatus === | 159 | stores!.app.updateStatus === |
169 | stores.app.updateStatusTypes.AVAILABLE || | 160 | stores!.app.updateStatusTypes.AVAILABLE || |
170 | stores.app.updateStatus === | 161 | stores!.app.updateStatus === |
171 | stores.app.updateStatusTypes.DOWNLOADED) && ( | 162 | stores!.app.updateStatusTypes.DOWNLOADED) && ( |
172 | <span className="update-available">•</span> | 163 | <span className="update-available">•</span> |
173 | )} | 164 | )} |
174 | </NavLink> | 165 | </NavLink> |
@@ -195,7 +186,8 @@ class SettingsNavigation extends Component { | |||
195 | <span className="settings-navigation__expander" /> | 186 | <span className="settings-navigation__expander" /> |
196 | <button | 187 | <button |
197 | type="button" | 188 | type="button" |
198 | to="/auth/logout" | 189 | // @ts-ignore |
190 | to="/auth/logout" // TODO - [TS DEBT] Need to check if button take this prop | ||
199 | className="settings-navigation__link" | 191 | className="settings-navigation__link" |
200 | onClick={this.handleLogout.bind(this)} | 192 | onClick={this.handleLogout.bind(this)} |
201 | > | 193 | > |
@@ -208,6 +200,4 @@ class SettingsNavigation extends Component { | |||
208 | } | 200 | } |
209 | } | 201 | } |
210 | 202 | ||
211 | export default injectIntl( | 203 | export default injectIntl(SettingsNavigation); |
212 | inject('stores', 'actions')(observer(SettingsNavigation)), | ||
213 | ); | ||
diff --git a/src/components/settings/recipes/RecipeItem.js b/src/components/settings/recipes/RecipeItem.tsx index df5b42222..432e4e6a1 100644 --- a/src/components/settings/recipes/RecipeItem.js +++ b/src/components/settings/recipes/RecipeItem.tsx | |||
@@ -1,14 +1,17 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, MouseEventHandler } from 'react'; |
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
3 | import RecipePreview from '../../../models/RecipePreview'; | ||
4 | 4 | ||
5 | import RecipePreviewModel from '../../../models/RecipePreview'; | 5 | interface IProps { |
6 | recipe: RecipePreview; | ||
7 | onClick: MouseEventHandler<HTMLButtonElement>; | ||
8 | } | ||
6 | 9 | ||
7 | class RecipeItem extends Component { | 10 | @observer |
8 | static propTypes = { | 11 | class RecipeItem extends Component<IProps> { |
9 | recipe: PropTypes.instanceOf(RecipePreviewModel).isRequired, | 12 | constructor(props: IProps) { |
10 | onClick: PropTypes.func.isRequired, | 13 | super(props); |
11 | }; | 14 | } |
12 | 15 | ||
13 | render() { | 16 | render() { |
14 | const { recipe, onClick } = this.props; | 17 | const { recipe, onClick } = this.props; |
@@ -18,7 +21,7 @@ class RecipeItem extends Component { | |||
18 | {recipe.isDevRecipe && ( | 21 | {recipe.isDevRecipe && ( |
19 | <span className="recipe-teaser__dev-badge">dev</span> | 22 | <span className="recipe-teaser__dev-badge">dev</span> |
20 | )} | 23 | )} |
21 | <img src={recipe.icons.svg} className="recipe-teaser__icon" alt="" /> | 24 | <img src={recipe.icons?.svg} className="recipe-teaser__icon" alt="" /> |
22 | <span className="recipe-teaser__label">{recipe.name}</span> | 25 | <span className="recipe-teaser__label">{recipe.name}</span> |
23 | {recipe.aliases && recipe.aliases.length > 0 && ( | 26 | {recipe.aliases && recipe.aliases.length > 0 && ( |
24 | <span className="recipe-teaser__alias_label"> | 27 | <span className="recipe-teaser__alias_label"> |
@@ -30,4 +33,4 @@ class RecipeItem extends Component { | |||
30 | } | 33 | } |
31 | } | 34 | } |
32 | 35 | ||
33 | export default observer(RecipeItem); | 36 | export default RecipeItem; |
diff --git a/src/components/settings/recipes/RecipesDashboard.jsx b/src/components/settings/recipes/RecipesDashboard.tsx index d6150d300..fc687bc79 100644 --- a/src/components/settings/recipes/RecipesDashboard.jsx +++ b/src/components/settings/recipes/RecipesDashboard.tsx | |||
@@ -1,17 +1,14 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import { observer } from 'mobx-react'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
4 | import { defineMessages, injectIntl } from 'react-intl'; | ||
5 | import { NavLink } from 'react-router-dom'; | 4 | import { NavLink } from 'react-router-dom'; |
6 | 5 | import withStyles, { WithStylesProps } from 'react-jss'; | |
7 | import injectSheet from 'react-jss'; | ||
8 | |||
9 | import { mdiOpenInNew } from '@mdi/js'; | 6 | import { mdiOpenInNew } from '@mdi/js'; |
10 | import Button from '../../ui/button'; | 7 | import Button from '../../ui/button'; |
11 | import Input from '../../ui/input/index'; | 8 | import Input from '../../ui/input/index'; |
12 | import { H1, H2, H3 } from '../../ui/headline'; | 9 | import { H1, H2, H3 } from '../../ui/headline'; |
13 | import SearchInput from '../../ui/SearchInput'; | 10 | import SearchInput from '../../ui/SearchInput'; |
14 | import Infobox from '../../ui/Infobox'; | 11 | import Infobox from '../../ui/infobox'; |
15 | import RecipeItem from './RecipeItem'; | 12 | import RecipeItem from './RecipeItem'; |
16 | import Loader from '../../ui/Loader'; | 13 | import Loader from '../../ui/Loader'; |
17 | import Appear from '../../ui/effects/Appear'; | 14 | import Appear from '../../ui/effects/Appear'; |
@@ -109,28 +106,32 @@ const styles = { | |||
109 | }, | 106 | }, |
110 | }; | 107 | }; |
111 | 108 | ||
112 | class RecipesDashboard extends Component { | 109 | interface IProps extends WithStylesProps<typeof styles>, WrappedComponentProps { |
113 | static propTypes = { | 110 | recipes: RecipePreview[]; |
114 | recipes: MobxPropTypes.arrayOrObservableArray.isRequired, | 111 | customWebsiteRecipe?: RecipePreview; |
115 | customWebsiteRecipe: PropTypes.instanceOf(RecipePreview).isRequired, | 112 | isLoading: boolean; |
116 | isLoading: PropTypes.bool.isRequired, | 113 | hasLoadedRecipes: boolean; |
117 | hasLoadedRecipes: PropTypes.bool.isRequired, | 114 | showAddServiceInterface: (...args: any[]) => void; |
118 | showAddServiceInterface: PropTypes.func.isRequired, | 115 | searchRecipes: (e: string | null) => void; |
119 | searchRecipes: PropTypes.func.isRequired, | 116 | resetSearch: () => void; |
120 | resetSearch: PropTypes.func.isRequired, | 117 | serviceStatus: string[]; |
121 | serviceStatus: MobxPropTypes.arrayOrObservableArray.isRequired, | 118 | searchNeedle: string | null; |
122 | searchNeedle: PropTypes.string, | 119 | recipeFilter?: string; |
123 | recipeFilter: PropTypes.string, | 120 | recipeDirectory: string; |
124 | recipeDirectory: PropTypes.string.isRequired, | 121 | openRecipeDirectory: () => void; |
125 | openRecipeDirectory: PropTypes.func.isRequired, | 122 | openDevDocs: () => void; |
126 | openDevDocs: PropTypes.func.isRequired, | 123 | } |
127 | classes: PropTypes.object.isRequired, | 124 | |
128 | }; | 125 | interface IState { |
126 | searchNeedle: string | null; | ||
127 | recipeFilter: string; | ||
128 | } | ||
129 | 129 | ||
130 | static defaultProps = { | 130 | @observer |
131 | searchNeedle: '', | 131 | class RecipesDashboard extends Component<IProps, IState> { |
132 | recipeFilter: 'all', | 132 | constructor(props: IProps) { |
133 | }; | 133 | super(props); |
134 | } | ||
134 | 135 | ||
135 | render() { | 136 | render() { |
136 | const { | 137 | const { |
@@ -141,15 +142,15 @@ class RecipesDashboard extends Component { | |||
141 | showAddServiceInterface, | 142 | showAddServiceInterface, |
142 | searchRecipes, | 143 | searchRecipes, |
143 | resetSearch, | 144 | resetSearch, |
144 | serviceStatus, | 145 | serviceStatus = 'all', |
145 | searchNeedle, | 146 | searchNeedle = '', |
146 | recipeFilter, | 147 | recipeFilter, |
147 | recipeDirectory, | 148 | recipeDirectory, |
148 | openRecipeDirectory, | 149 | openRecipeDirectory, |
149 | openDevDocs, | 150 | openDevDocs, |
150 | classes, | 151 | classes, |
152 | intl, | ||
151 | } = this.props; | 153 | } = this.props; |
152 | const { intl } = this.props; | ||
153 | 154 | ||
154 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); | 155 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); |
155 | const devRecipes = recipes.filter(r => r.isDevRecipe); | 156 | const devRecipes = recipes.filter(r => r.isDevRecipe); |
@@ -307,5 +308,5 @@ class RecipesDashboard extends Component { | |||
307 | } | 308 | } |
308 | 309 | ||
309 | export default injectIntl( | 310 | export default injectIntl( |
310 | injectSheet(styles, { injectTheme: true })(observer(RecipesDashboard)), | 311 | withStyles(styles, { injectTheme: true })(RecipesDashboard), |
311 | ); | 312 | ); |
diff --git a/src/components/ui/SearchInput.tsx b/src/components/ui/SearchInput.tsx index 6a8c4de8f..39b8f95bf 100644 --- a/src/components/ui/SearchInput.tsx +++ b/src/components/ui/SearchInput.tsx | |||
@@ -1,43 +1,35 @@ | |||
1 | import { ChangeEvent, Component } from 'react'; | 1 | import { ChangeEvent, Component, ReactElement } from 'react'; |
2 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
3 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
4 | import { debounce } from 'lodash'; | 4 | import { debounce, noop } from 'lodash'; |
5 | import { mdiCloseCircleOutline, mdiMagnify } from '@mdi/js'; | 5 | import { mdiCloseCircleOutline, mdiMagnify } from '@mdi/js'; |
6 | import Icon from './icon'; | 6 | import Icon from './icon'; |
7 | 7 | ||
8 | type Props = { | 8 | interface IProps { |
9 | value: string; | 9 | value?: string; |
10 | placeholder: string; | 10 | placeholder: string; |
11 | className: string; | 11 | className?: string; |
12 | onChange: (e: ChangeEvent<HTMLInputElement>) => void; | 12 | onChange?: (e: string) => void; |
13 | onReset: () => void; | 13 | onReset: () => void; |
14 | name: string; | 14 | name?: string; |
15 | throttle: boolean; | 15 | throttle?: boolean; |
16 | throttleDelay: number; | 16 | throttleDelay?: number; |
17 | autoFocus: boolean; | 17 | autoFocus?: boolean; |
18 | }; | 18 | } |
19 | 19 | ||
20 | // Should this file be converted into the coding style similar to './toggle/index.tsx'? | 20 | interface IState { |
21 | class SearchInput extends Component<Props> { | 21 | value: string; |
22 | static defaultProps = { | 22 | } |
23 | value: '', | 23 | |
24 | placeholder: '', | 24 | @observer |
25 | className: '', | 25 | class SearchInput extends Component<IProps, IState> { |
26 | name: 'searchInput', | 26 | input: HTMLInputElement | null = null; |
27 | throttle: false, | 27 | |
28 | throttleDelay: 250, | 28 | constructor(props: IProps) { |
29 | onChange: () => null, | ||
30 | onReset: () => null, | ||
31 | autoFocus: false, | ||
32 | }; | ||
33 | |||
34 | input = null; | ||
35 | |||
36 | constructor(props: Props) { | ||
37 | super(props); | 29 | super(props); |
38 | 30 | ||
39 | this.state = { | 31 | this.state = { |
40 | value: props.value, | 32 | value: props.value || '', |
41 | }; | 33 | }; |
42 | 34 | ||
43 | this.throttledOnChange = debounce( | 35 | this.throttledOnChange = debounce( |
@@ -46,47 +38,47 @@ class SearchInput extends Component<Props> { | |||
46 | ); | 38 | ); |
47 | } | 39 | } |
48 | 40 | ||
49 | componentDidMount() { | 41 | componentDidMount(): void { |
50 | const { autoFocus } = this.props; | 42 | const { autoFocus = false } = this.props; |
51 | 43 | ||
52 | if (autoFocus) { | 44 | if (autoFocus && this.input) { |
53 | // @ts-expect-error Object is possibly 'null'. | ||
54 | this.input.focus(); | 45 | this.input.focus(); |
55 | } | 46 | } |
56 | } | 47 | } |
57 | 48 | ||
58 | onChange(e: ChangeEvent<HTMLInputElement>) { | 49 | onChange(e: ChangeEvent<HTMLInputElement>): void { |
59 | const { throttle, onChange } = this.props; | 50 | const { throttle = false, onChange = noop } = this.props; |
60 | const { value } = e.target; | 51 | const { value } = e.target; |
61 | this.setState({ value }); | 52 | this.setState({ value }); |
62 | 53 | ||
63 | if (throttle) { | 54 | if (throttle) { |
64 | e.persist(); | 55 | e.persist(); |
65 | // @ts-expect-error Argument of type 'string' is not assignable to parameter of type 'ChangeEvent<HTMLInputElement>'. | ||
66 | this.throttledOnChange(value); | 56 | this.throttledOnChange(value); |
67 | } else { | 57 | } else { |
68 | // @ts-expect-error Argument of type 'string' is not assignable to parameter of type 'ChangeEvent<HTMLInputElement>'. | ||
69 | onChange(value); | 58 | onChange(value); |
70 | } | 59 | } |
71 | } | 60 | } |
72 | 61 | ||
73 | throttledOnChange(e: ChangeEvent<HTMLInputElement>) { | 62 | throttledOnChange(e: string): void { |
74 | const { onChange } = this.props; | 63 | const { onChange = noop } = this.props; |
75 | 64 | ||
76 | onChange(e); | 65 | onChange(e); |
77 | } | 66 | } |
78 | 67 | ||
79 | reset() { | 68 | reset(): void { |
80 | const { onReset } = this.props; | 69 | const { onReset = noop } = this.props; |
81 | this.setState({ value: '' }); | 70 | this.setState({ value: '' }); |
82 | 71 | ||
83 | onReset(); | 72 | onReset(); |
84 | } | 73 | } |
85 | 74 | ||
86 | render() { | 75 | render(): ReactElement { |
87 | const { className, name, placeholder } = this.props; | 76 | const { |
88 | // @ts-expect-error Property 'value' does not exist on type 'Readonly<{}>'. | 77 | className = '', |
89 | const { value } = this.state; | 78 | name = 'searchInput', |
79 | placeholder = '', | ||
80 | } = this.props; | ||
81 | const { value = '' } = this.state; | ||
90 | 82 | ||
91 | return ( | 83 | return ( |
92 | <div className={classnames([className, 'search-input'])}> | 84 | <div className={classnames([className, 'search-input'])}> |
@@ -100,13 +92,12 @@ class SearchInput extends Component<Props> { | |||
100 | value={value} | 92 | value={value} |
101 | onChange={e => this.onChange(e)} | 93 | onChange={e => this.onChange(e)} |
102 | ref={ref => { | 94 | ref={ref => { |
103 | // @ts-expect-error Type 'HTMLInputElement | null' is not assignable to type 'null'. | ||
104 | this.input = ref; | 95 | this.input = ref; |
105 | }} | 96 | }} |
106 | /> | 97 | /> |
107 | </label> | 98 | </label> |
108 | {value.length > 0 && ( | 99 | {value.length > 0 && ( |
109 | <span onClick={() => this.reset()}> | 100 | <span onClick={() => this.reset()} onKeyDown={noop}> |
110 | <Icon icon={mdiCloseCircleOutline} /> | 101 | <Icon icon={mdiCloseCircleOutline} /> |
111 | </span> | 102 | </span> |
112 | )} | 103 | )} |
@@ -115,4 +106,4 @@ class SearchInput extends Component<Props> { | |||
115 | } | 106 | } |
116 | } | 107 | } |
117 | 108 | ||
118 | export default observer(SearchInput); | 109 | export default SearchInput; |
diff --git a/src/components/ui/effects/Appear.tsx b/src/components/ui/effects/Appear.tsx index 416017c83..bf097b6a6 100644 --- a/src/components/ui/effects/Appear.tsx +++ b/src/components/ui/effects/Appear.tsx | |||
@@ -1,16 +1,16 @@ | |||
1 | import { ReactNode, useEffect, useState } from 'react'; | 1 | import { ReactElement, ReactNode, useEffect, useState } from 'react'; |
2 | import { CSSTransitionGroup } from 'react-transition-group'; | 2 | import { CSSTransitionGroup } from 'react-transition-group'; |
3 | 3 | ||
4 | type Props = { | 4 | interface IProps { |
5 | children: ReactNode; | 5 | children: ReactNode; |
6 | transitionName: string; | 6 | transitionName?: string; |
7 | className?: string; | 7 | className?: string; |
8 | }; | 8 | } |
9 | const Appear = ({ | 9 | const Appear = ({ |
10 | children, | 10 | children, |
11 | transitionName = 'fadeIn', | 11 | transitionName = 'fadeIn', |
12 | className = '', | 12 | className = '', |
13 | }: Props) => { | 13 | }: IProps): ReactElement | null => { |
14 | const [mounted, setMounted] = useState(false); | 14 | const [mounted, setMounted] = useState(false); |
15 | 15 | ||
16 | useEffect(() => { | 16 | useEffect(() => { |
@@ -36,8 +36,4 @@ const Appear = ({ | |||
36 | ); | 36 | ); |
37 | }; | 37 | }; |
38 | 38 | ||
39 | Appear.defaultProps = { | ||
40 | className: '', | ||
41 | }; | ||
42 | |||
43 | export default Appear; | 39 | export default Appear; |