Skip to content

Commit 22b852e

Browse files
committed
fix(react): resolve errors with JSX and types
1 parent 30b1e7f commit 22b852e

File tree

6 files changed

+292
-288
lines changed

6 files changed

+292
-288
lines changed
Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { JSX as LocalJSX } from '@ionic/core/components';
2-
import React from 'react';
2+
import React, { type PropsWithChildren } from 'react';
33

44
import type { IonContextInterface } from '../contexts/IonContext';
55
import { IonContext } from '../contexts/IonContext';
@@ -9,53 +9,46 @@ import { IonOverlayManager } from './IonOverlayManager';
99
import type { IonicReactProps } from './IonicReactProps';
1010
import { IonAppInner } from './inner-proxies';
1111

12-
type Props = LocalJSX.IonApp &
13-
IonicReactProps & {
14-
ref?: React.Ref<HTMLIonAppElement>;
12+
type Props = PropsWithChildren<LocalJSX.IonApp & IonicReactProps & {
13+
ref?: React.Ref<HTMLIonAppElement>;
14+
}>;
15+
16+
export class IonApp extends React.Component<Props> {
17+
addOverlayCallback?: (id: string, overlay: ReactComponentOrElement, containerElement: HTMLDivElement) => void;
18+
removeOverlayCallback?: (id: string) => void;
19+
20+
constructor(props: Props) {
21+
super(props);
22+
}
23+
24+
ionContext: IonContextInterface = {
25+
addOverlay: (id: string, overlay: ReactComponentOrElement, containerElement: HTMLDivElement) => {
26+
if (this.addOverlayCallback) {
27+
this.addOverlayCallback(id, overlay, containerElement);
28+
}
29+
},
30+
removeOverlay: (id: string) => {
31+
if (this.removeOverlayCallback) {
32+
this.removeOverlayCallback(id);
33+
}
34+
},
1535
};
1636

17-
export const IonApp = /*@__PURE__*/ (() =>
18-
class extends React.Component<Props> {
19-
addOverlayCallback?: (id: string, overlay: ReactComponentOrElement, containerElement: HTMLDivElement) => void;
20-
removeOverlayCallback?: (id: string) => void;
21-
22-
constructor(props: Props) {
23-
super(props);
24-
}
25-
26-
/*
27-
Wire up methods to call into IonOverlayManager
28-
*/
29-
ionContext: IonContextInterface = {
30-
addOverlay: (id: string, overlay: ReactComponentOrElement, containerElement: HTMLDivElement) => {
31-
if (this.addOverlayCallback) {
32-
this.addOverlayCallback(id, overlay, containerElement);
33-
}
34-
},
35-
removeOverlay: (id: string) => {
36-
if (this.removeOverlayCallback) {
37-
this.removeOverlayCallback(id);
38-
}
39-
},
40-
};
41-
42-
render() {
43-
return (
44-
<IonContext.Provider value={this.ionContext}>
45-
<IonAppInner {...this.props}>{this.props.children}</IonAppInner>
46-
<IonOverlayManager
47-
onAddOverlay={(callback) => {
48-
this.addOverlayCallback = callback;
49-
}}
50-
onRemoveOverlay={(callback) => {
51-
this.removeOverlayCallback = callback;
52-
}}
53-
/>
54-
</IonContext.Provider>
55-
);
56-
}
57-
58-
static get displayName() {
59-
return 'IonApp';
60-
}
61-
})();
37+
render() {
38+
return (
39+
<IonContext.Provider value={this.ionContext}>
40+
<IonAppInner {...this.props}>{this.props.children}</IonAppInner>
41+
<IonOverlayManager
42+
onAddOverlay={(callback) => {
43+
this.addOverlayCallback = callback;
44+
}}
45+
onRemoveOverlay={(callback) => {
46+
this.removeOverlayCallback = callback;
47+
}}
48+
/>
49+
</IonContext.Provider>
50+
);
51+
}
52+
53+
static displayName = 'IonApp';
54+
}
Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,50 @@
11
import type { JSX as LocalJSX } from '@ionic/core/components';
2-
import React from 'react';
2+
import React, { type PropsWithChildren } from 'react';
33

44
import { NavContext } from '../../contexts/NavContext';
55
import type { IonicReactProps } from '../IonicReactProps';
66
import { IonBackButtonInner } from '../inner-proxies';
77

8-
type Props = Omit<LocalJSX.IonBackButton, 'icon'> &
9-
IonicReactProps & {
10-
icon?:
11-
| {
12-
ios: string;
13-
md: string;
14-
}
15-
| string;
16-
ref?: React.Ref<HTMLIonBackButtonElement>;
17-
};
18-
19-
export const IonBackButton = /*@__PURE__*/ (() =>
20-
class extends React.Component<Props> {
21-
context!: React.ContextType<typeof NavContext>;
22-
23-
clickButton = (e: React.MouseEvent) => {
24-
/**
25-
* If ion-back-button is being used inside
26-
* of ion-nav then we should not interact with
27-
* the router.
28-
*/
29-
if (e.target && (e.target as HTMLElement).closest('ion-nav') !== null) {
30-
return;
31-
}
32-
33-
const { defaultHref, routerAnimation } = this.props;
34-
35-
if (this.context.hasIonicRouter()) {
36-
e.stopPropagation();
37-
this.context.goBack(defaultHref, routerAnimation);
38-
} else if (defaultHref !== undefined) {
39-
window.location.href = defaultHref;
40-
}
41-
};
42-
43-
render() {
44-
return <IonBackButtonInner onClick={this.clickButton} {...this.props}></IonBackButtonInner>;
8+
type Props = PropsWithChildren<LocalJSX.IonBackButton & IonicReactProps & {
9+
ref?: React.Ref<HTMLIonBackButtonElement>;
10+
}>;
11+
12+
export class IonBackButton extends React.Component<Props> {
13+
context!: React.ContextType<typeof NavContext>;
14+
15+
clickButton = (e: React.MouseEvent) => {
16+
/**
17+
* If ion-back-button is being used inside
18+
* of ion-nav then we should not interact with
19+
* the router.
20+
*/
21+
if (e.target && (e.target as HTMLElement).closest('ion-nav') !== null) {
22+
return;
4523
}
4624

47-
static get displayName() {
48-
return 'IonBackButton';
49-
}
25+
const { defaultHref, routerAnimation } = this.props;
5026

51-
static get contextType() {
52-
return NavContext;
27+
if (this.context.hasIonicRouter()) {
28+
e.stopPropagation();
29+
this.context.goBack(defaultHref, routerAnimation);
30+
} else if (defaultHref !== undefined) {
31+
window.location.href = defaultHref;
5332
}
54-
})();
33+
};
34+
35+
render() {
36+
return <IonBackButtonInner onClick={this.clickButton} {...this.props}></IonBackButtonInner>;
37+
}
38+
39+
static get displayName() {
40+
return 'IonBackButton';
41+
}
42+
43+
static get contextType() {
44+
return NavContext;
45+
}
46+
47+
shouldComponentUpdate(_nextProps: Readonly<Props>): boolean {
48+
return true;
49+
}
50+
}

packages/react/src/components/navigation/IonTabButton.tsx

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,45 @@ type Props = LocalJSX.IonTabButton &
1313
onPointerDown?: React.PointerEventHandler<HTMLIonTabButtonElement>;
1414
onTouchEnd?: React.TouchEventHandler<HTMLIonTabButtonElement>;
1515
onTouchMove?: React.TouchEventHandler<HTMLIonTabButtonElement>;
16+
children?: React.ReactNode;
1617
};
1718

18-
export const IonTabButton = /*@__PURE__*/ (() =>
19-
class extends React.Component<Props> {
20-
constructor(props: Props) {
21-
super(props);
22-
this.handleIonTabButtonClick = this.handleIonTabButtonClick.bind(this);
23-
}
19+
export class IonTabButton extends React.Component<Props> {
20+
shouldComponentUpdate(_nextProps: Readonly<Props>, _nextState: Readonly<{}>): boolean {
21+
return true;
22+
}
2423

25-
handleIonTabButtonClick() {
26-
if (this.props.onClick) {
27-
this.props.onClick(
28-
new CustomEvent('ionTabButtonClick', {
29-
detail: {
30-
tab: this.props.tab,
31-
href: this.props.href,
32-
routeOptions: this.props.routerOptions,
33-
},
34-
})
35-
);
36-
}
37-
}
24+
constructor(props: Props) {
25+
super(props);
26+
this.handleIonTabButtonClick = this.handleIonTabButtonClick.bind(this);
27+
}
3828

39-
render() {
40-
/**
41-
* onClick is excluded from the props, since it has a custom
42-
* implementation within IonTabBar.tsx. Calling onClick within this
43-
* component would result in duplicate handler calls.
44-
*/
45-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
46-
const { onClick, ...rest } = this.props;
47-
return <IonTabButtonInner onIonTabButtonClick={this.handleIonTabButtonClick} {...rest}></IonTabButtonInner>;
29+
handleIonTabButtonClick() {
30+
if (this.props.onClick) {
31+
this.props.onClick(
32+
new CustomEvent('ionTabButtonClick', {
33+
detail: {
34+
tab: this.props.tab,
35+
href: this.props.href,
36+
routeOptions: this.props.routerOptions,
37+
},
38+
})
39+
);
4840
}
41+
}
4942

50-
static get displayName() {
51-
return 'IonTabButton';
52-
}
53-
})();
43+
render() {
44+
/**
45+
* onClick is excluded from the props, since it has a custom
46+
* implementation within IonTabBar.tsx. Calling onClick within this
47+
* component would result in duplicate handler calls.
48+
*/
49+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
50+
const { onClick, ...rest } = this.props;
51+
return <IonTabButtonInner onIonTabButtonClick={this.handleIonTabButtonClick} {...rest}></IonTabButtonInner>;
52+
}
53+
54+
static get displayName() {
55+
return 'IonTabButton';
56+
}
57+
}

0 commit comments

Comments
 (0)