mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
chore(react): adding prettier and formating files
This commit is contained in:
@@ -1,8 +1,23 @@
|
||||
import { Animation, AnimationCallbackOptions, AnimationDirection, AnimationFill, AnimationKeyFrames, AnimationLifecycle, createAnimation } from '@ionic/core';
|
||||
import {
|
||||
Animation,
|
||||
AnimationCallbackOptions,
|
||||
AnimationDirection,
|
||||
AnimationFill,
|
||||
AnimationKeyFrames,
|
||||
AnimationLifecycle,
|
||||
createAnimation,
|
||||
} from '@ionic/core';
|
||||
import React from 'react';
|
||||
|
||||
interface PartialPropertyValue { property: string; value: any; }
|
||||
interface PropertyValue { property: string; fromValue: any; toValue: any; }
|
||||
interface PartialPropertyValue {
|
||||
property: string;
|
||||
value: any;
|
||||
}
|
||||
interface PropertyValue {
|
||||
property: string;
|
||||
fromValue: any;
|
||||
toValue: any;
|
||||
}
|
||||
|
||||
export interface CreateAnimationProps {
|
||||
delay?: number;
|
||||
@@ -27,7 +42,7 @@ export interface CreateAnimationProps {
|
||||
beforeAddClass?: string | string[];
|
||||
beforeRemoveClass?: string | string[];
|
||||
|
||||
onFinish?: { callback: AnimationLifecycle; opts?: AnimationCallbackOptions; };
|
||||
onFinish?: { callback: AnimationLifecycle; opts?: AnimationCallbackOptions };
|
||||
|
||||
keyframes?: AnimationKeyFrames;
|
||||
from?: PartialPropertyValue[] | PartialPropertyValue;
|
||||
@@ -39,9 +54,9 @@ export interface CreateAnimationProps {
|
||||
stop?: boolean;
|
||||
destroy?: boolean;
|
||||
|
||||
progressStart?: { forceLinearEasing: boolean, step?: number };
|
||||
progressStart?: { forceLinearEasing: boolean; step?: number };
|
||||
progressStep?: { step: number };
|
||||
progressEnd?: { playTo: 0 | 1 | undefined, step: number, dur?: number };
|
||||
progressEnd?: { playTo: 0 | 1 | undefined; step: number; dur?: number };
|
||||
}
|
||||
|
||||
export class CreateAnimation extends React.PureComponent<CreateAnimationProps> {
|
||||
@@ -84,14 +99,29 @@ export class CreateAnimation extends React.PureComponent<CreateAnimationProps> {
|
||||
const { children } = this.props;
|
||||
return (
|
||||
<>
|
||||
{React.Children.map(children, ((child, id) => React.cloneElement(child as any, { ref: (el: any) => this.nodes.set(id, el) })))}
|
||||
{React.Children.map(children, (child, id) =>
|
||||
React.cloneElement(child as any, { ref: (el: any) => this.nodes.set(id, el) })
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const checkConfig = (animation: Animation, currentProps: any = {}, prevProps: any = {}) => {
|
||||
const reservedProps = ['children', 'progressStart', 'progressStep', 'progressEnd', 'pause', 'stop', 'destroy', 'play', 'from', 'to', 'fromTo', 'onFinish'];
|
||||
const reservedProps = [
|
||||
'children',
|
||||
'progressStart',
|
||||
'progressStep',
|
||||
'progressEnd',
|
||||
'pause',
|
||||
'stop',
|
||||
'destroy',
|
||||
'play',
|
||||
'from',
|
||||
'to',
|
||||
'fromTo',
|
||||
'onFinish',
|
||||
];
|
||||
for (const key in currentProps) {
|
||||
if (
|
||||
currentProps.hasOwnProperty(key) &&
|
||||
@@ -104,33 +134,37 @@ const checkConfig = (animation: Animation, currentProps: any = {}, prevProps: an
|
||||
|
||||
const fromValues = currentProps.from;
|
||||
if (fromValues && fromValues !== prevProps.from) {
|
||||
const values = (Array.isArray(fromValues)) ? fromValues : [fromValues];
|
||||
values.forEach(val => animation.from(val.property, val.value));
|
||||
const values = Array.isArray(fromValues) ? fromValues : [fromValues];
|
||||
values.forEach((val) => animation.from(val.property, val.value));
|
||||
}
|
||||
|
||||
const toValues = currentProps.to;
|
||||
if (toValues && toValues !== prevProps.to) {
|
||||
const values = (Array.isArray(toValues)) ? toValues : [toValues];
|
||||
values.forEach(val => animation.to(val.property, val.value));
|
||||
const values = Array.isArray(toValues) ? toValues : [toValues];
|
||||
values.forEach((val) => animation.to(val.property, val.value));
|
||||
}
|
||||
|
||||
const fromToValues = currentProps.fromTo;
|
||||
if (fromToValues && fromToValues !== prevProps.fromTo) {
|
||||
const values = (Array.isArray(fromToValues)) ? fromToValues : [fromToValues];
|
||||
values.forEach(val => animation.fromTo(val.property, val.fromValue, val.toValue));
|
||||
const values = Array.isArray(fromToValues) ? fromToValues : [fromToValues];
|
||||
values.forEach((val) => animation.fromTo(val.property, val.fromValue, val.toValue));
|
||||
}
|
||||
|
||||
const onFinishValues = currentProps.onFinish;
|
||||
if (onFinishValues && onFinishValues !== prevProps.onFinish) {
|
||||
const values = (Array.isArray(onFinishValues)) ? onFinishValues : [onFinishValues];
|
||||
values.forEach(val => animation.onFinish(val.callback, val.opts));
|
||||
const values = Array.isArray(onFinishValues) ? onFinishValues : [onFinishValues];
|
||||
values.forEach((val) => animation.onFinish(val.callback, val.opts));
|
||||
}
|
||||
};
|
||||
|
||||
const checkProgress = (animation: Animation, currentProps: any = {}, prevProps: any = {}) => {
|
||||
const { progressStart, progressStep, progressEnd } = currentProps;
|
||||
|
||||
if (progressStart && (prevProps.progressStart?.forceLinearEasing !== progressStart?.forceLinearEasing || prevProps.progressStart?.step !== progressStart?.step)) {
|
||||
if (
|
||||
progressStart &&
|
||||
(prevProps.progressStart?.forceLinearEasing !== progressStart?.forceLinearEasing ||
|
||||
prevProps.progressStart?.step !== progressStart?.step)
|
||||
) {
|
||||
animation.progressStart(progressStart.forceLinearEasing, progressStart.step);
|
||||
}
|
||||
|
||||
@@ -138,7 +172,12 @@ const checkProgress = (animation: Animation, currentProps: any = {}, prevProps:
|
||||
animation.progressStep(progressStep.step);
|
||||
}
|
||||
|
||||
if (progressEnd && (prevProps.progressEnd?.playTo !== progressEnd?.playTo || prevProps.progressEnd?.step !== progressEnd?.step || prevProps?.dur !== progressEnd?.dur)) {
|
||||
if (
|
||||
progressEnd &&
|
||||
(prevProps.progressEnd?.playTo !== progressEnd?.playTo ||
|
||||
prevProps.progressEnd?.step !== progressEnd?.step ||
|
||||
prevProps?.dur !== progressEnd?.dur)
|
||||
) {
|
||||
animation.progressEnd(progressEnd.playTo, progressEnd.step, progressEnd.dur);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { ActionSheetButton as ActionSheetButtonCore, ActionSheetOptions as ActionSheetOptionsCore, actionSheetController as actionSheetControllerCore } from '@ionic/core';
|
||||
import {
|
||||
ActionSheetButton as ActionSheetButtonCore,
|
||||
ActionSheetOptions as ActionSheetOptionsCore,
|
||||
actionSheetController as actionSheetControllerCore,
|
||||
} from '@ionic/core';
|
||||
|
||||
import { createOverlayComponent } from './createOverlayComponent';
|
||||
|
||||
export interface ActionSheetButton extends Omit<ActionSheetButtonCore, 'icon'> {
|
||||
icon?: {
|
||||
ios: string;
|
||||
md: string;
|
||||
} | string;
|
||||
icon?:
|
||||
| {
|
||||
ios: string;
|
||||
md: string;
|
||||
}
|
||||
| string;
|
||||
}
|
||||
|
||||
export interface ActionSheetOptions extends Omit<ActionSheetOptionsCore, 'buttons'> {
|
||||
@@ -15,8 +21,12 @@ export interface ActionSheetOptions extends Omit<ActionSheetOptionsCore, 'button
|
||||
|
||||
const actionSheetController = {
|
||||
create: (options: ActionSheetOptions) => actionSheetControllerCore.create(options as any),
|
||||
dismiss: (data?: any, role?: string | undefined, id?: string | undefined) => actionSheetControllerCore.dismiss(data, role, id),
|
||||
getTop: () => actionSheetControllerCore.getTop()
|
||||
dismiss: (data?: any, role?: string | undefined, id?: string | undefined) =>
|
||||
actionSheetControllerCore.dismiss(data, role, id),
|
||||
getTop: () => actionSheetControllerCore.getTop(),
|
||||
};
|
||||
|
||||
export const IonActionSheet = /*@__PURE__*/createOverlayComponent<ActionSheetOptions, HTMLIonActionSheetElement>('IonActionSheet', actionSheetController);
|
||||
export const IonActionSheet = /*@__PURE__*/ createOverlayComponent<
|
||||
ActionSheetOptions,
|
||||
HTMLIonActionSheetElement
|
||||
>('IonActionSheet', actionSheetController);
|
||||
|
||||
@@ -2,4 +2,7 @@ import { AlertOptions, alertController } from '@ionic/core';
|
||||
|
||||
import { createControllerComponent } from './createControllerComponent';
|
||||
|
||||
export const IonAlert = /*@__PURE__*/createControllerComponent<AlertOptions, HTMLIonAlertElement>('IonAlert', alertController);
|
||||
export const IonAlert = /*@__PURE__*/ createControllerComponent<AlertOptions, HTMLIonAlertElement>(
|
||||
'IonAlert',
|
||||
alertController
|
||||
);
|
||||
|
||||
@@ -26,11 +26,13 @@ type InternalProps = IonIconProps & {
|
||||
};
|
||||
|
||||
class IonIconContainer extends React.PureComponent<InternalProps> {
|
||||
|
||||
constructor(props: InternalProps) {
|
||||
super(props);
|
||||
if (this.props.name) {
|
||||
deprecationWarning('icon-name', 'In Ionic React, you import icons from "ionicons/icons" and set the icon you imported to the "icon" property. Setting the "name" property has no effect.');
|
||||
deprecationWarning(
|
||||
'icon-name',
|
||||
'In Ionic React, you import icons from "ionicons/icons" and set the icon you imported to the "icon" property. Setting the "name" property has no effect.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,4 +63,7 @@ class IonIconContainer extends React.PureComponent<InternalProps> {
|
||||
}
|
||||
}
|
||||
|
||||
export const IonIcon = createForwardRef<IonIconProps & IonicReactProps, HTMLIonIconElement>(IonIconContainer, 'IonIcon');
|
||||
export const IonIcon = createForwardRef<IonIconProps & IonicReactProps, HTMLIonIconElement>(
|
||||
IonIconContainer,
|
||||
'IonIcon'
|
||||
);
|
||||
|
||||
@@ -2,4 +2,7 @@ import { LoadingOptions, loadingController } from '@ionic/core';
|
||||
|
||||
import { createControllerComponent } from './createControllerComponent';
|
||||
|
||||
export const IonLoading = /*@__PURE__*/createControllerComponent<LoadingOptions, HTMLIonLoadingElement>('IonLoading', loadingController);
|
||||
export const IonLoading = /*@__PURE__*/ createControllerComponent<
|
||||
LoadingOptions,
|
||||
HTMLIonLoadingElement
|
||||
>('IonLoading', loadingController);
|
||||
|
||||
@@ -6,4 +6,7 @@ export type ReactModalOptions = Omit<ModalOptions, 'component' | 'componentProps
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const IonModal = /*@__PURE__*/createOverlayComponent<ReactModalOptions, HTMLIonModalElement>('IonModal', modalController);
|
||||
export const IonModal = /*@__PURE__*/ createOverlayComponent<
|
||||
ReactModalOptions,
|
||||
HTMLIonModalElement
|
||||
>('IonModal', modalController);
|
||||
|
||||
@@ -6,8 +6,7 @@ import PageManager from '../routing/PageManager';
|
||||
import { IonicReactProps } from './IonicReactProps';
|
||||
import { createForwardRef } from './utils';
|
||||
|
||||
interface IonPageProps extends IonicReactProps {
|
||||
}
|
||||
interface IonPageProps extends IonicReactProps {}
|
||||
|
||||
interface IonPageInternalProps extends IonPageProps {
|
||||
forwardedRef?: React.RefObject<HTMLDivElement>;
|
||||
@@ -23,21 +22,23 @@ class IonPageInternal extends React.Component<IonPageInternalProps> {
|
||||
render() {
|
||||
const { className, children, forwardedRef, ...props } = this.props;
|
||||
|
||||
return (
|
||||
this.context.hasIonicRouter() ? (
|
||||
<PageManager
|
||||
className={className ? `${className}` : ''}
|
||||
routeInfo={this.context.routeInfo}
|
||||
forwardedRef={forwardedRef}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</PageManager>
|
||||
) : (
|
||||
<div className={className ? `ion-page ${className}` : 'ion-page'} ref={forwardedRef} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
return this.context.hasIonicRouter() ? (
|
||||
<PageManager
|
||||
className={className ? `${className}` : ''}
|
||||
routeInfo={this.context.routeInfo}
|
||||
forwardedRef={forwardedRef}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</PageManager>
|
||||
) : (
|
||||
<div
|
||||
className={className ? `ion-page ${className}` : 'ion-page'}
|
||||
ref={forwardedRef}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,4 +2,7 @@ import { PickerOptions, pickerController } from '@ionic/core';
|
||||
|
||||
import { createControllerComponent } from './createControllerComponent';
|
||||
|
||||
export const IonPicker = /*@__PURE__*/createControllerComponent<PickerOptions, HTMLIonPickerElement>('IonPicker', pickerController);
|
||||
export const IonPicker = /*@__PURE__*/ createControllerComponent<
|
||||
PickerOptions,
|
||||
HTMLIonPickerElement
|
||||
>('IonPicker', pickerController);
|
||||
|
||||
@@ -6,4 +6,7 @@ export type ReactPopoverOptions = Omit<PopoverOptions, 'component' | 'componentP
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const IonPopover = /*@__PURE__*/createOverlayComponent<ReactPopoverOptions, HTMLIonPopoverElement>('IonPopover', popoverController);
|
||||
export const IonPopover = /*@__PURE__*/ createOverlayComponent<
|
||||
ReactPopoverOptions,
|
||||
HTMLIonPopoverElement
|
||||
>('IonPopover', popoverController);
|
||||
|
||||
@@ -9,30 +9,25 @@ export interface IonRedirectProps {
|
||||
routerOptions?: unknown;
|
||||
}
|
||||
|
||||
interface IonRedirectState {
|
||||
|
||||
}
|
||||
interface IonRedirectState {}
|
||||
|
||||
export class IonRedirect extends React.PureComponent<IonRedirectProps, IonRedirectState> {
|
||||
|
||||
context!: React.ContextType<typeof NavContext>;
|
||||
|
||||
render() {
|
||||
|
||||
const IonRedirectInner = this.context.getIonRedirect();
|
||||
|
||||
if (!this.context.hasIonicRouter() || !IonRedirect) {
|
||||
console.error('You either do not have an Ionic Router package, or your router does not support using <IonRedirect>');
|
||||
console.error(
|
||||
'You either do not have an Ionic Router package, or your router does not support using <IonRedirect>'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<IonRedirectInner {...this.props} />
|
||||
);
|
||||
return <IonRedirectInner {...this.props} />;
|
||||
}
|
||||
|
||||
static get contextType() {
|
||||
return NavContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,30 +10,25 @@ export interface IonRouteProps {
|
||||
disableIonPageManagement?: boolean;
|
||||
}
|
||||
|
||||
interface IonRouteState {
|
||||
|
||||
}
|
||||
interface IonRouteState {}
|
||||
|
||||
export class IonRoute extends React.PureComponent<IonRouteProps, IonRouteState> {
|
||||
|
||||
context!: React.ContextType<typeof NavContext>;
|
||||
|
||||
render() {
|
||||
|
||||
const IonRouteInner = this.context.getIonRoute();
|
||||
|
||||
if (!this.context.hasIonicRouter() || !IonRoute) {
|
||||
console.error('You either do not have an Ionic Router package, or your router does not support using <IonRoute>');
|
||||
console.error(
|
||||
'You either do not have an Ionic Router package, or your router does not support using <IonRoute>'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<IonRouteInner {...this.props} />
|
||||
);
|
||||
return <IonRouteInner {...this.props} />;
|
||||
}
|
||||
|
||||
static get contextType() {
|
||||
return NavContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,13 @@ import { RouteInfo } from '../models/RouteInfo';
|
||||
|
||||
export interface IonRouterContextState {
|
||||
routeInfo: RouteInfo;
|
||||
push: (pathname: string, routerDirection?: RouterDirection, routeAction?: RouteAction, routerOptions?: RouterOptions, animationBuilder?: AnimationBuilder) => void;
|
||||
push: (
|
||||
pathname: string,
|
||||
routerDirection?: RouterDirection,
|
||||
routeAction?: RouteAction,
|
||||
routerOptions?: RouterOptions,
|
||||
animationBuilder?: AnimationBuilder
|
||||
) => void;
|
||||
back: (animationBuilder?: AnimationBuilder) => void;
|
||||
canGoBack: () => boolean;
|
||||
nativeBack: () => void;
|
||||
@@ -14,10 +20,18 @@ export interface IonRouterContextState {
|
||||
|
||||
export const IonRouterContext = React.createContext<IonRouterContextState>({
|
||||
routeInfo: undefined as any,
|
||||
push: () => { throw new Error('An Ionic Router is required for IonRouterContext'); },
|
||||
back: () => { throw new Error('An Ionic Router is required for IonRouterContext'); },
|
||||
canGoBack: () => { throw new Error('An Ionic Router is required for IonRouterContext'); },
|
||||
nativeBack: () => { throw new Error('An Ionic Router is required for IonRouterContext'); }
|
||||
push: () => {
|
||||
throw new Error('An Ionic Router is required for IonRouterContext');
|
||||
},
|
||||
back: () => {
|
||||
throw new Error('An Ionic Router is required for IonRouterContext');
|
||||
},
|
||||
canGoBack: () => {
|
||||
throw new Error('An Ionic Router is required for IonRouterContext');
|
||||
},
|
||||
nativeBack: () => {
|
||||
throw new Error('An Ionic Router is required for IonRouterContext');
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -29,8 +43,8 @@ export function useIonRouter(): UseIonRouterResult {
|
||||
back: context.back,
|
||||
push: context.push,
|
||||
goBack: context.back,
|
||||
canGoBack: context.canGoBack
|
||||
}
|
||||
canGoBack: context.canGoBack,
|
||||
};
|
||||
}
|
||||
|
||||
type UseIonRouterResult = {
|
||||
@@ -47,7 +61,13 @@ type UseIonRouterResult = {
|
||||
* @param routerOptions - Optional - Any additional parameters to pass to the router
|
||||
* @param animationBuilder - Optional - A custom transition animation to use
|
||||
*/
|
||||
push(pathname: string, routerDirection?: RouterDirection, routeAction?: RouteAction, routerOptions?: RouterOptions, animationBuilder?: AnimationBuilder): void;
|
||||
push(
|
||||
pathname: string,
|
||||
routerDirection?: RouterDirection,
|
||||
routeAction?: RouteAction,
|
||||
routerOptions?: RouterOptions,
|
||||
animationBuilder?: AnimationBuilder
|
||||
): void;
|
||||
/**
|
||||
* Navigates backwards in history, using the IonRouter to determine history
|
||||
* @param animationBuilder - Optional - A custom transition animation to use
|
||||
@@ -57,4 +77,4 @@ type UseIonRouterResult = {
|
||||
* Determines if there are any additional routes in the the Router's history. However, routing is not prevented if the browser's history has more entries. Returns true if more entries exist, false if not.
|
||||
*/
|
||||
canGoBack(): boolean;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { JSX as LocalJSX } from '@ionic/core';
|
||||
import React from 'react';
|
||||
|
||||
@@ -19,8 +18,7 @@ interface InternalProps extends Props {
|
||||
forwardedRef?: React.RefObject<HTMLIonRouterOutletElement>;
|
||||
}
|
||||
|
||||
interface InternalState {
|
||||
}
|
||||
interface InternalState {}
|
||||
|
||||
class IonRouterOutletContainer extends React.Component<InternalProps, InternalState> {
|
||||
context!: React.ContextType<typeof NavContext>;
|
||||
@@ -30,32 +28,29 @@ class IonRouterOutletContainer extends React.Component<InternalProps, InternalSt
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const StackManager = this.context.getStackManager();
|
||||
const { children, forwardedRef, ...props } = this.props;
|
||||
|
||||
return (
|
||||
this.context.hasIonicRouter() ? (
|
||||
props.ionPage ? (
|
||||
<OutletPageManager
|
||||
StackManager={StackManager}
|
||||
routeInfo={this.context.routeInfo}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</OutletPageManager>
|
||||
) : (
|
||||
<StackManager routeInfo={this.context.routeInfo}>
|
||||
<IonRouterOutletInner {...props} forwardedRef={forwardedRef}>
|
||||
{children}
|
||||
</IonRouterOutletInner>
|
||||
</StackManager>
|
||||
)
|
||||
return this.context.hasIonicRouter() ? (
|
||||
props.ionPage ? (
|
||||
<OutletPageManager
|
||||
StackManager={StackManager}
|
||||
routeInfo={this.context.routeInfo}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</OutletPageManager>
|
||||
) : (
|
||||
<IonRouterOutletInner ref={forwardedRef} {...this.props}>
|
||||
{this.props.children}
|
||||
<StackManager routeInfo={this.context.routeInfo}>
|
||||
<IonRouterOutletInner {...props} forwardedRef={forwardedRef}>
|
||||
{children}
|
||||
</IonRouterOutletInner>
|
||||
)
|
||||
</StackManager>
|
||||
)
|
||||
) : (
|
||||
<IonRouterOutletInner ref={forwardedRef} {...this.props}>
|
||||
{this.props.children}
|
||||
</IonRouterOutletInner>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,4 +59,7 @@ class IonRouterOutletContainer extends React.Component<InternalProps, InternalSt
|
||||
}
|
||||
}
|
||||
|
||||
export const IonRouterOutlet = createForwardRef<Props & IonicReactProps, HTMLIonRouterOutletElement>(IonRouterOutletContainer, 'IonRouterOutlet');
|
||||
export const IonRouterOutlet = createForwardRef<
|
||||
Props & IonicReactProps,
|
||||
HTMLIonRouterOutletElement
|
||||
>(IonRouterOutletContainer, 'IonRouterOutlet');
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { ToastButton as ToastButtonCore, ToastOptions as ToastOptionsCore, toastController as toastControllerCore } from '@ionic/core';
|
||||
import {
|
||||
ToastButton as ToastButtonCore,
|
||||
ToastOptions as ToastOptionsCore,
|
||||
toastController as toastControllerCore,
|
||||
} from '@ionic/core';
|
||||
|
||||
import { createControllerComponent } from './createControllerComponent';
|
||||
|
||||
export interface ToastButton extends Omit<ToastButtonCore, 'icon'> {
|
||||
icon?: {
|
||||
ios: string;
|
||||
md: string;
|
||||
} | string;
|
||||
icon?:
|
||||
| {
|
||||
ios: string;
|
||||
md: string;
|
||||
}
|
||||
| string;
|
||||
}
|
||||
|
||||
export interface ToastOptions extends Omit<ToastOptionsCore, 'buttons'> {
|
||||
@@ -15,8 +21,12 @@ export interface ToastOptions extends Omit<ToastOptionsCore, 'buttons'> {
|
||||
|
||||
const toastController = {
|
||||
create: (options: ToastOptions) => toastControllerCore.create(options as any),
|
||||
dismiss: (data?: any, role?: string | undefined, id?: string | undefined) => toastControllerCore.dismiss(data, role, id),
|
||||
getTop: () => toastControllerCore.getTop()
|
||||
dismiss: (data?: any, role?: string | undefined, id?: string | undefined) =>
|
||||
toastControllerCore.dismiss(data, role, id),
|
||||
getTop: () => toastControllerCore.getTop(),
|
||||
};
|
||||
|
||||
export const IonToast = /*@__PURE__*/createControllerComponent<ToastOptions, HTMLIonToastElement>('IonToast', toastController);
|
||||
export const IonToast = /*@__PURE__*/ createControllerComponent<ToastOptions, HTMLIonToastElement>(
|
||||
'IonToast',
|
||||
toastController
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
export interface IonicReactProps {
|
||||
class?: string;
|
||||
className?: string;
|
||||
style?: {[key: string]: any };
|
||||
style?: { [key: string]: any };
|
||||
}
|
||||
|
||||
@@ -4,23 +4,22 @@ import { IonButton } from '../index';
|
||||
import { defineCustomElements } from '@ionic/core/loader';
|
||||
|
||||
describe('IonButton', () => {
|
||||
|
||||
beforeAll(async (done) => {
|
||||
await defineCustomElements(window);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
it('should render a button', () => {
|
||||
const { getByText, } = render(<IonButton>my button</IonButton>);
|
||||
const { getByText } = render(<IonButton>my button</IonButton>);
|
||||
const button = getByText('my button');
|
||||
expect(button).toBeDefined();
|
||||
});
|
||||
|
||||
it('when the button is clicked, it should call the click handler', () => {
|
||||
const clickSpy = jest.fn();
|
||||
const { getByText, } = render(<IonButton onClick={clickSpy}>my button</IonButton>);
|
||||
const { getByText } = render(<IonButton onClick={clickSpy}>my button</IonButton>);
|
||||
const button = getByText('my button');
|
||||
fireEvent.click(button);
|
||||
expect(clickSpy).toHaveBeenCalled();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { IonTabs, IonTabButton, IonLabel, IonIcon, IonTabBar} from '../index';
|
||||
import { IonTabs, IonTabButton, IonLabel, IonIcon, IonTabBar } from '../index';
|
||||
import { render, cleanup } from '@testing-library/react';
|
||||
import { IonRouterOutlet } from '../IonRouterOutlet';
|
||||
|
||||
afterEach(cleanup)
|
||||
afterEach(cleanup);
|
||||
|
||||
describe('IonTabs', () => {
|
||||
test('should render happy path', () => {
|
||||
@@ -37,7 +37,12 @@ describe('IonTabs', () => {
|
||||
|
||||
expect(container.children[0].children[1].tagName).toEqual('ION-TAB-BAR');
|
||||
expect(container.children[0].children[1].children.length).toEqual(4);
|
||||
expect(Array.from(container.children[0].children[1].children).map(c => c.tagName)).toEqual(['ION-TAB-BUTTON', 'ION-TAB-BUTTON', 'ION-TAB-BUTTON', 'ION-TAB-BUTTON']);
|
||||
expect(Array.from(container.children[0].children[1].children).map((c) => c.tagName)).toEqual([
|
||||
'ION-TAB-BUTTON',
|
||||
'ION-TAB-BUTTON',
|
||||
'ION-TAB-BUTTON',
|
||||
'ION-TAB-BUTTON',
|
||||
]);
|
||||
});
|
||||
|
||||
test('should allow for conditional children', () => {
|
||||
@@ -45,12 +50,12 @@ describe('IonTabs', () => {
|
||||
<IonTabs>
|
||||
<IonRouterOutlet></IonRouterOutlet>
|
||||
<IonTabBar slot="bottom">
|
||||
{false &&
|
||||
<IonTabButton tab="schedule">
|
||||
<IonLabel>Schedule</IonLabel>
|
||||
<IonIcon name="schedule"></IonIcon>
|
||||
</IonTabButton>
|
||||
}
|
||||
{false && (
|
||||
<IonTabButton tab="schedule">
|
||||
<IonLabel>Schedule</IonLabel>
|
||||
<IonIcon name="schedule"></IonIcon>
|
||||
</IonTabButton>
|
||||
)}
|
||||
<IonTabButton tab="speakers">
|
||||
<IonLabel>Speakers</IonLabel>
|
||||
<IonIcon name="speakers"></IonIcon>
|
||||
@@ -73,6 +78,10 @@ describe('IonTabs', () => {
|
||||
|
||||
expect(container.children[0].children[1].tagName).toEqual('ION-TAB-BAR');
|
||||
expect(container.children[0].children[1].children.length).toEqual(3);
|
||||
expect(Array.from(container.children[0].children[1].children).map(c => c.tagName)).toEqual(['ION-TAB-BUTTON', 'ION-TAB-BUTTON', 'ION-TAB-BUTTON']);
|
||||
expect(Array.from(container.children[0].children[1].children).map((c) => c.tagName)).toEqual([
|
||||
'ION-TAB-BUTTON',
|
||||
'ION-TAB-BUTTON',
|
||||
'ION-TAB-BUTTON',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,11 +11,7 @@ describe('createComponent - events', () => {
|
||||
const FakeOnClick = jest.fn((e) => e);
|
||||
const IonButton = createReactComponent<JSX.IonButton, HTMLIonButtonElement>('ion-button');
|
||||
|
||||
const { getByText } = render(
|
||||
<IonButton onClick={FakeOnClick}>
|
||||
ButtonNameA
|
||||
</IonButton>
|
||||
);
|
||||
const { getByText } = render(<IonButton onClick={FakeOnClick}>ButtonNameA</IonButton>);
|
||||
fireEvent.click(getByText('ButtonNameA'));
|
||||
expect(FakeOnClick).toBeCalledTimes(1);
|
||||
});
|
||||
@@ -24,11 +20,7 @@ describe('createComponent - events', () => {
|
||||
const FakeIonFocus = jest.fn((e) => e);
|
||||
const IonInput = createReactComponent<JSX.IonInput, HTMLIonInputElement>('ion-input');
|
||||
|
||||
const { getByText } = render(
|
||||
<IonInput onIonFocus={FakeIonFocus}>
|
||||
ButtonNameA
|
||||
</IonInput>
|
||||
);
|
||||
const { getByText } = render(<IonInput onIonFocus={FakeIonFocus}>ButtonNameA</IonInput>);
|
||||
const ionInputItem = getByText('ButtonNameA');
|
||||
expect(Object.keys((ionInputItem as any).__events)).toEqual(['ionFocus']);
|
||||
});
|
||||
@@ -39,11 +31,7 @@ describe('createComponent - ref', () => {
|
||||
const ionButtonRef: React.RefObject<any> = React.createRef();
|
||||
const IonButton = createReactComponent<JSX.IonButton, HTMLIonButtonElement>('ion-button');
|
||||
|
||||
const { getByText } = render(
|
||||
<IonButton ref={ionButtonRef}>
|
||||
ButtonNameA
|
||||
</IonButton>
|
||||
)
|
||||
const { getByText } = render(<IonButton ref={ionButtonRef}>ButtonNameA</IonButton>);
|
||||
const ionButtonItem = getByText('ButtonNameA');
|
||||
expect(ionButtonRef.current).toEqual(ionButtonItem);
|
||||
});
|
||||
@@ -65,8 +53,8 @@ describe('createComponent - strict mode', () => {
|
||||
});
|
||||
|
||||
describe('when working with css classes', () => {
|
||||
const myClass = 'my-class'
|
||||
const myClass2 = 'my-class2'
|
||||
const myClass = 'my-class';
|
||||
const myClass2 = 'my-class2';
|
||||
const customClass = 'custom-class';
|
||||
|
||||
describe('when a class is added to className', () => {
|
||||
@@ -74,11 +62,7 @@ describe('when working with css classes', () => {
|
||||
let button: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
renderResult = render(
|
||||
<IonButton className={myClass}>
|
||||
Hello!
|
||||
</IonButton>
|
||||
);
|
||||
renderResult = render(<IonButton className={myClass}>Hello!</IonButton>);
|
||||
button = renderResult.getByText(/Hello/);
|
||||
});
|
||||
|
||||
@@ -89,11 +73,7 @@ describe('when working with css classes', () => {
|
||||
it('when a class is added to class list outside of React, then that class should still be in class list when rendered again', () => {
|
||||
button.classList.add(customClass);
|
||||
expect(button.classList.contains(customClass)).toBeTruthy();
|
||||
renderResult.rerender(
|
||||
<IonButton className={myClass}>
|
||||
Hello!
|
||||
</IonButton>
|
||||
);
|
||||
renderResult.rerender(<IonButton className={myClass}>Hello!</IonButton>);
|
||||
expect(button.classList.contains(customClass)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -103,11 +83,7 @@ describe('when working with css classes', () => {
|
||||
let button: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
renderResult = render(
|
||||
<IonButton className={myClass + ' ' + myClass2}>
|
||||
Hello!
|
||||
</IonButton>
|
||||
);
|
||||
renderResult = render(<IonButton className={myClass + ' ' + myClass2}>Hello!</IonButton>);
|
||||
button = renderResult.getByText(/Hello/);
|
||||
});
|
||||
|
||||
@@ -120,11 +96,7 @@ describe('when working with css classes', () => {
|
||||
expect(button.classList.contains(myClass)).toBeTruthy();
|
||||
expect(button.classList.contains(myClass2)).toBeTruthy();
|
||||
|
||||
renderResult.rerender(
|
||||
<IonButton className={myClass}>
|
||||
Hello!
|
||||
</IonButton>
|
||||
);
|
||||
renderResult.rerender(<IonButton className={myClass}>Hello!</IonButton>);
|
||||
|
||||
expect(button.classList.contains(myClass)).toBeTruthy();
|
||||
expect(button.classList.contains(myClass2)).toBeFalsy();
|
||||
@@ -136,15 +108,11 @@ describe('when working with css classes', () => {
|
||||
expect(button.classList.contains(myClass2)).toBeTruthy();
|
||||
expect(button.classList.contains(customClass)).toBeTruthy();
|
||||
|
||||
renderResult.rerender(
|
||||
<IonButton className={myClass}>
|
||||
Hello!
|
||||
</IonButton>
|
||||
);
|
||||
renderResult.rerender(<IonButton className={myClass}>Hello!</IonButton>);
|
||||
|
||||
expect(button.classList.contains(myClass)).toBeTruthy();
|
||||
expect(button.classList.contains(myClass)).toBeTruthy();
|
||||
expect(button.classList.contains(myClass2)).toBeFalsy();
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,9 +13,9 @@ describe('isCoveredByReact', () => {
|
||||
|
||||
describe('syncEvent', () => {
|
||||
it('should add event on sync and readd on additional syncs', () => {
|
||||
var div = document.createElement("div");
|
||||
const addEventListener = jest.spyOn(div, "addEventListener");
|
||||
const removeEventListener = jest.spyOn(div, "removeEventListener");
|
||||
var div = document.createElement('div');
|
||||
const addEventListener = jest.spyOn(div, 'addEventListener');
|
||||
const removeEventListener = jest.spyOn(div, 'removeEventListener');
|
||||
const ionClickCallback = jest.fn();
|
||||
|
||||
utils.syncEvent(div, 'ionClick', ionClickCallback);
|
||||
@@ -26,29 +26,28 @@ describe('syncEvent', () => {
|
||||
expect(removeEventListener).toHaveBeenCalledWith('ionClick', expect.any(Function));
|
||||
expect(addEventListener).toHaveBeenCalledWith('ionClick', expect.any(Function));
|
||||
|
||||
const event = new CustomEvent('ionClick', { detail: 'test'});
|
||||
const event = new CustomEvent('ionClick', { detail: 'test' });
|
||||
div.dispatchEvent(event);
|
||||
expect(ionClickCallback).toHaveBeenCalled();
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('attachProps', () => {
|
||||
it('should pass props to a dom node', () => {
|
||||
const onIonClickCallback = () => {};
|
||||
|
||||
var div = document.createElement("div");
|
||||
var div = document.createElement('div');
|
||||
utils.attachProps(div, {
|
||||
'children': [],
|
||||
'style': 'color: red',
|
||||
'ref': () => {},
|
||||
'onClick': () => {},
|
||||
'onIonClick': onIonClickCallback,
|
||||
'testprop': ['red']
|
||||
children: [],
|
||||
style: 'color: red',
|
||||
ref: () => {},
|
||||
onClick: () => {},
|
||||
onIonClick: onIonClickCallback,
|
||||
testprop: ['red'],
|
||||
});
|
||||
|
||||
expect((div as any).testprop).toEqual(['red']);
|
||||
expect(div).toHaveStyle(`display: block;`);
|
||||
expect(Object.keys((div as any).__events)).toEqual(['ionClick']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -5,7 +5,13 @@ import { NavContext } from '../contexts/NavContext';
|
||||
import { RouterOptions } from '../models';
|
||||
import { RouterDirection } from '../models/RouterDirection';
|
||||
|
||||
import { attachProps, camelToDashCase, createForwardRef, dashToPascalCase, isCoveredByReact } from './utils';
|
||||
import {
|
||||
attachProps,
|
||||
camelToDashCase,
|
||||
createForwardRef,
|
||||
dashToPascalCase,
|
||||
isCoveredByReact,
|
||||
} from './utils';
|
||||
|
||||
interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<ElementType> {
|
||||
forwardedRef?: React.Ref<ElementType>;
|
||||
@@ -48,9 +54,15 @@ export const createReactComponent = <PropType, ElementType>(
|
||||
const { routerLink, routerDirection, routerOptions, routerAnimation } = this.props;
|
||||
if (routerLink !== undefined) {
|
||||
e.preventDefault();
|
||||
this.context.navigate(routerLink, routerDirection, undefined, routerAnimation, routerOptions);
|
||||
this.context.navigate(
|
||||
routerLink,
|
||||
routerDirection,
|
||||
undefined,
|
||||
routerAnimation,
|
||||
routerOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { children, forwardedRef, style, className, ref, ...cProps } = this.props;
|
||||
@@ -70,7 +82,7 @@ export const createReactComponent = <PropType, ElementType>(
|
||||
const newProps: IonicReactInternalProps<PropType> = {
|
||||
...propsToPass,
|
||||
ref: forwardedRef || this.ref,
|
||||
style
|
||||
style,
|
||||
};
|
||||
|
||||
if (routerLinkComponent) {
|
||||
@@ -90,11 +102,7 @@ export const createReactComponent = <PropType, ElementType>(
|
||||
}
|
||||
}
|
||||
|
||||
return React.createElement(
|
||||
tagName,
|
||||
newProps,
|
||||
children
|
||||
);
|
||||
return React.createElement(tagName, newProps, children);
|
||||
}
|
||||
|
||||
static get displayName() {
|
||||
|
||||
@@ -16,18 +16,22 @@ export interface ReactControllerProps {
|
||||
onWillPresent?: (event: CustomEvent<OverlayEventDetail>) => void;
|
||||
}
|
||||
|
||||
export const createControllerComponent = <OptionsType extends object, OverlayType extends OverlayBase>(
|
||||
export const createControllerComponent = <
|
||||
OptionsType extends object,
|
||||
OverlayType extends OverlayBase
|
||||
>(
|
||||
displayName: string,
|
||||
controller: { create: (options: OptionsType) => Promise<OverlayType>; }
|
||||
controller: { create: (options: OptionsType) => Promise<OverlayType> }
|
||||
) => {
|
||||
const didDismissEventName = `on${displayName}DidDismiss`;
|
||||
const didPresentEventName = `on${displayName}DidPresent`;
|
||||
const willDismissEventName = `on${displayName}WillDismiss`;
|
||||
const willPresentEventName = `on${displayName}WillPresent`;
|
||||
|
||||
type Props = OptionsType & ReactControllerProps & {
|
||||
forwardedRef?: React.RefObject<OverlayType>;
|
||||
};
|
||||
type Props = OptionsType &
|
||||
ReactControllerProps & {
|
||||
forwardedRef?: React.RefObject<OverlayType>;
|
||||
};
|
||||
|
||||
class Overlay extends React.Component<Props> {
|
||||
overlay?: OverlayType;
|
||||
@@ -51,7 +55,9 @@ export const createControllerComponent = <OptionsType extends object, OverlayTyp
|
||||
|
||||
componentWillUnmount() {
|
||||
this.isUnmounted = true;
|
||||
if (this.overlay) { this.overlay.dismiss(); }
|
||||
if (this.overlay) {
|
||||
this.overlay.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
async componentDidUpdate(prevProps: Props) {
|
||||
@@ -73,16 +79,30 @@ export const createControllerComponent = <OptionsType extends object, OverlayTyp
|
||||
}
|
||||
|
||||
async present(prevProps?: Props) {
|
||||
const { isOpen, onDidDismiss, onDidPresent, onWillDismiss, onWillPresent, ...cProps } = this.props;
|
||||
const {
|
||||
isOpen,
|
||||
onDidDismiss,
|
||||
onDidPresent,
|
||||
onWillDismiss,
|
||||
onWillPresent,
|
||||
...cProps
|
||||
} = this.props;
|
||||
this.overlay = await controller.create({
|
||||
...cProps as any
|
||||
...(cProps as any),
|
||||
});
|
||||
attachProps(this.overlay, {
|
||||
[didDismissEventName]: this.handleDismiss,
|
||||
[didPresentEventName]: (e: CustomEvent) => this.props.onDidPresent && this.props.onDidPresent(e),
|
||||
[willDismissEventName]: (e: CustomEvent) => this.props.onWillDismiss && this.props.onWillDismiss(e),
|
||||
[willPresentEventName]: (e: CustomEvent) => this.props.onWillPresent && this.props.onWillPresent(e)
|
||||
}, prevProps);
|
||||
attachProps(
|
||||
this.overlay,
|
||||
{
|
||||
[didDismissEventName]: this.handleDismiss,
|
||||
[didPresentEventName]: (e: CustomEvent) =>
|
||||
this.props.onDidPresent && this.props.onDidPresent(e),
|
||||
[willDismissEventName]: (e: CustomEvent) =>
|
||||
this.props.onWillDismiss && this.props.onWillDismiss(e),
|
||||
[willPresentEventName]: (e: CustomEvent) =>
|
||||
this.props.onWillPresent && this.props.onWillPresent(e),
|
||||
},
|
||||
prevProps
|
||||
);
|
||||
// Check isOpen again since the value could have changed during the async call to controller.create
|
||||
// It's also possible for the component to have become unmounted.
|
||||
if (this.props.isOpen === true && this.isUnmounted === false) {
|
||||
|
||||
@@ -18,18 +18,22 @@ export interface ReactOverlayProps {
|
||||
onWillPresent?: (event: CustomEvent<OverlayEventDetail>) => void;
|
||||
}
|
||||
|
||||
export const createOverlayComponent = <OverlayComponent extends object, OverlayType extends OverlayElement>(
|
||||
export const createOverlayComponent = <
|
||||
OverlayComponent extends object,
|
||||
OverlayType extends OverlayElement
|
||||
>(
|
||||
displayName: string,
|
||||
controller: { create: (options: any) => Promise<OverlayType>; }
|
||||
controller: { create: (options: any) => Promise<OverlayType> }
|
||||
) => {
|
||||
const didDismissEventName = `on${displayName}DidDismiss`;
|
||||
const didPresentEventName = `on${displayName}DidPresent`;
|
||||
const willDismissEventName = `on${displayName}WillDismiss`;
|
||||
const willPresentEventName = `on${displayName}WillPresent`;
|
||||
|
||||
type Props = OverlayComponent & ReactOverlayProps & {
|
||||
forwardedRef?: React.RefObject<OverlayType>;
|
||||
};
|
||||
type Props = OverlayComponent &
|
||||
ReactOverlayProps & {
|
||||
forwardedRef?: React.RefObject<OverlayType>;
|
||||
};
|
||||
|
||||
class Overlay extends React.Component<Props> {
|
||||
overlay?: OverlayType;
|
||||
@@ -54,7 +58,9 @@ export const createOverlayComponent = <OverlayComponent extends object, OverlayT
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.overlay) { this.overlay.dismiss(); }
|
||||
if (this.overlay) {
|
||||
this.overlay.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
handleDismiss(event: CustomEvent<OverlayEventDetail<any>>) {
|
||||
@@ -80,20 +86,31 @@ export const createOverlayComponent = <OverlayComponent extends object, OverlayT
|
||||
}
|
||||
|
||||
async present(prevProps?: Props) {
|
||||
const { children, isOpen, onDidDismiss, onDidPresent, onWillDismiss, onWillPresent, ...cProps } = this.props;
|
||||
const {
|
||||
children,
|
||||
isOpen,
|
||||
onDidDismiss,
|
||||
onDidPresent,
|
||||
onWillDismiss,
|
||||
onWillPresent,
|
||||
...cProps
|
||||
} = this.props;
|
||||
const elementProps = {
|
||||
...cProps,
|
||||
ref: this.props.forwardedRef,
|
||||
[didDismissEventName]: this.handleDismiss,
|
||||
[didPresentEventName]: (e: CustomEvent) => this.props.onDidPresent && this.props.onDidPresent(e),
|
||||
[willDismissEventName]: (e: CustomEvent) => this.props.onWillDismiss && this.props.onWillDismiss(e),
|
||||
[willPresentEventName]: (e: CustomEvent) => this.props.onWillPresent && this.props.onWillPresent(e)
|
||||
[didPresentEventName]: (e: CustomEvent) =>
|
||||
this.props.onDidPresent && this.props.onDidPresent(e),
|
||||
[willDismissEventName]: (e: CustomEvent) =>
|
||||
this.props.onWillDismiss && this.props.onWillDismiss(e),
|
||||
[willPresentEventName]: (e: CustomEvent) =>
|
||||
this.props.onWillPresent && this.props.onWillPresent(e),
|
||||
};
|
||||
|
||||
this.overlay = await controller.create({
|
||||
...elementProps,
|
||||
component: this.el,
|
||||
componentProps: {}
|
||||
componentProps: {},
|
||||
});
|
||||
|
||||
if (this.props.forwardedRef) {
|
||||
@@ -106,10 +123,7 @@ export const createOverlayComponent = <OverlayComponent extends object, OverlayT
|
||||
}
|
||||
|
||||
render() {
|
||||
return ReactDOM.createPortal(
|
||||
this.props.isOpen ? this.props.children : null,
|
||||
this.el
|
||||
);
|
||||
return ReactDOM.createPortal(this.props.isOpen ? this.props.children : null, this.el);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,41 @@
|
||||
|
||||
import { defineCustomElements } from '@ionic/core/loader';
|
||||
import { addIcons } from 'ionicons';
|
||||
import { arrowBackSharp, caretBackSharp, chevronBack, chevronForward, close, closeCircle, closeSharp, menuOutline, menuSharp, reorderThreeOutline, reorderTwoSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
||||
export { Animation, AnimationBuilder, AnimationCallbackOptions, AnimationDirection, AnimationFill, AnimationKeyFrames, AnimationLifecycle, createAnimation, createGesture, AlertButton, AlertInput, Gesture, GestureConfig, GestureDetail, iosTransitionAnimation, IonicSafeString, mdTransitionAnimation, NavComponentWithProps, setupConfig } from '@ionic/core';
|
||||
import {
|
||||
arrowBackSharp,
|
||||
caretBackSharp,
|
||||
chevronBack,
|
||||
chevronForward,
|
||||
close,
|
||||
closeCircle,
|
||||
closeSharp,
|
||||
menuOutline,
|
||||
menuSharp,
|
||||
reorderThreeOutline,
|
||||
reorderTwoSharp,
|
||||
searchOutline,
|
||||
searchSharp,
|
||||
} from 'ionicons/icons';
|
||||
export {
|
||||
Animation,
|
||||
AnimationBuilder,
|
||||
AnimationCallbackOptions,
|
||||
AnimationDirection,
|
||||
AnimationFill,
|
||||
AnimationKeyFrames,
|
||||
AnimationLifecycle,
|
||||
createAnimation,
|
||||
createGesture,
|
||||
AlertButton,
|
||||
AlertInput,
|
||||
Gesture,
|
||||
GestureConfig,
|
||||
GestureDetail,
|
||||
iosTransitionAnimation,
|
||||
IonicSafeString,
|
||||
mdTransitionAnimation,
|
||||
NavComponentWithProps,
|
||||
setupConfig,
|
||||
} from '@ionic/core';
|
||||
export * from './proxies';
|
||||
|
||||
// createControllerComponent
|
||||
@@ -42,7 +75,7 @@ addIcons({
|
||||
'caret-back-sharp': caretBackSharp,
|
||||
'chevron-back': chevronBack,
|
||||
'chevron-forward': chevronForward,
|
||||
'close': close,
|
||||
close,
|
||||
'close-circle': closeCircle,
|
||||
'close-sharp': closeSharp,
|
||||
'menu-outline': menuOutline,
|
||||
|
||||
@@ -3,13 +3,28 @@ import { JSX as IoniconsJSX } from 'ionicons';
|
||||
|
||||
import { /*@__PURE__*/ createReactComponent } from './createComponent';
|
||||
|
||||
export const IonTabButtonInner = /*@__PURE__*/createReactComponent<JSX.IonTabButton & { onIonTabButtonClick?: (e: CustomEvent) => void; }, HTMLIonTabButtonElement>('ion-tab-button');
|
||||
export const IonTabBarInner = /*@__PURE__*/createReactComponent<JSX.IonTabBar, HTMLIonTabBarElement>('ion-tab-bar');
|
||||
export const IonBackButtonInner = /*@__PURE__*/createReactComponent<Omit<JSX.IonBackButton, 'icon'>, HTMLIonBackButtonElement>('ion-back-button');
|
||||
export const IonRouterOutletInner = /*@__PURE__*/createReactComponent<JSX.IonRouterOutlet & {
|
||||
setRef?: (val: HTMLIonRouterOutletElement) => void;
|
||||
forwardedRef?: React.RefObject<HTMLIonRouterOutletElement>;
|
||||
}, HTMLIonRouterOutletElement>('ion-router-outlet');
|
||||
export const IonTabButtonInner = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonTabButton & { onIonTabButtonClick?: (e: CustomEvent) => void },
|
||||
HTMLIonTabButtonElement
|
||||
>('ion-tab-button');
|
||||
export const IonTabBarInner = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonTabBar,
|
||||
HTMLIonTabBarElement
|
||||
>('ion-tab-bar');
|
||||
export const IonBackButtonInner = /*@__PURE__*/ createReactComponent<
|
||||
Omit<JSX.IonBackButton, 'icon'>,
|
||||
HTMLIonBackButtonElement
|
||||
>('ion-back-button');
|
||||
export const IonRouterOutletInner = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonRouterOutlet & {
|
||||
setRef?: (val: HTMLIonRouterOutletElement) => void;
|
||||
forwardedRef?: React.RefObject<HTMLIonRouterOutletElement>;
|
||||
},
|
||||
HTMLIonRouterOutletElement
|
||||
>('ion-router-outlet');
|
||||
|
||||
// ionicons
|
||||
export const IonIconInner = /*@__PURE__*/createReactComponent<IoniconsJSX.IonIcon, HTMLIonIconElement>('ion-icon');
|
||||
export const IonIconInner = /*@__PURE__*/ createReactComponent<
|
||||
IoniconsJSX.IonIcon,
|
||||
HTMLIonIconElement
|
||||
>('ion-icon');
|
||||
|
||||
@@ -5,38 +5,40 @@ import { NavContext } from '../../contexts/NavContext';
|
||||
import { IonicReactProps } from '../IonicReactProps';
|
||||
import { IonBackButtonInner } from '../inner-proxies';
|
||||
|
||||
type Props = Omit<LocalJSX.IonBackButton, 'icon'> & IonicReactProps & {
|
||||
icon?: {
|
||||
ios: string;
|
||||
md: string;
|
||||
} | string;
|
||||
ref?: React.RefObject<HTMLIonBackButtonElement>;
|
||||
};
|
||||
type Props = Omit<LocalJSX.IonBackButton, 'icon'> &
|
||||
IonicReactProps & {
|
||||
icon?:
|
||||
| {
|
||||
ios: string;
|
||||
md: string;
|
||||
}
|
||||
| string;
|
||||
ref?: React.RefObject<HTMLIonBackButtonElement>;
|
||||
};
|
||||
|
||||
export const IonBackButton = /*@__PURE__*/(() => class extends React.Component<Props> {
|
||||
context!: React.ContextType<typeof NavContext>;
|
||||
export const IonBackButton = /*@__PURE__*/ (() =>
|
||||
class extends React.Component<Props> {
|
||||
context!: React.ContextType<typeof NavContext>;
|
||||
|
||||
clickButton = (e: React.MouseEvent) => {
|
||||
const { defaultHref, routerAnimation } = this.props;
|
||||
if (this.context.hasIonicRouter()) {
|
||||
e.stopPropagation();
|
||||
this.context.goBack(defaultHref, routerAnimation);
|
||||
} else if (defaultHref !== undefined) {
|
||||
window.location.href = defaultHref;
|
||||
clickButton = (e: React.MouseEvent) => {
|
||||
const { defaultHref, routerAnimation } = this.props;
|
||||
if (this.context.hasIonicRouter()) {
|
||||
e.stopPropagation();
|
||||
this.context.goBack(defaultHref, routerAnimation);
|
||||
} else if (defaultHref !== undefined) {
|
||||
window.location.href = defaultHref;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return <IonBackButtonInner onClick={this.clickButton} {...this.props}></IonBackButtonInner>;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<IonBackButtonInner onClick={this.clickButton} {...this.props}></IonBackButtonInner>
|
||||
);
|
||||
}
|
||||
static get displayName() {
|
||||
return 'IonBackButton';
|
||||
}
|
||||
|
||||
static get displayName() {
|
||||
return 'IonBackButton';
|
||||
}
|
||||
|
||||
static get contextType() {
|
||||
return NavContext;
|
||||
}
|
||||
})();
|
||||
static get contextType() {
|
||||
return NavContext;
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -9,12 +9,13 @@ import { createForwardRef } from '../utils';
|
||||
|
||||
import { IonTabButton } from './IonTabButton';
|
||||
|
||||
type IonTabBarProps = LocalJSX.IonTabBar & IonicReactProps & {
|
||||
onIonTabsDidChange?: (event: CustomEvent<{ tab: string; }>) => void;
|
||||
onIonTabsWillChange?: (event: CustomEvent<{ tab: string; }>) => void;
|
||||
slot?: 'bottom' | 'top';
|
||||
style?: { [key: string]: string; };
|
||||
};
|
||||
type IonTabBarProps = LocalJSX.IonTabBar &
|
||||
IonicReactProps & {
|
||||
onIonTabsDidChange?: (event: CustomEvent<{ tab: string }>) => void;
|
||||
onIonTabsWillChange?: (event: CustomEvent<{ tab: string }>) => void;
|
||||
slot?: 'bottom' | 'top';
|
||||
style?: { [key: string]: string };
|
||||
};
|
||||
|
||||
interface InternalProps extends IonTabBarProps {
|
||||
forwardedRef?: React.RefObject<HTMLIonIconElement>;
|
||||
@@ -31,7 +32,7 @@ interface TabUrls {
|
||||
|
||||
interface IonTabBarState {
|
||||
activeTab?: string;
|
||||
tabs: { [key: string]: TabUrls; };
|
||||
tabs: { [key: string]: TabUrls };
|
||||
}
|
||||
|
||||
class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarState> {
|
||||
@@ -39,20 +40,31 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
|
||||
constructor(props: InternalProps) {
|
||||
super(props);
|
||||
const tabs: { [key: string]: TabUrls; } = {};
|
||||
const tabs: { [key: string]: TabUrls } = {};
|
||||
React.Children.forEach((props as any).children, (child: any) => {
|
||||
if (child != null && typeof child === 'object' && child.props && child.type === IonTabButton) {
|
||||
if (
|
||||
child != null &&
|
||||
typeof child === 'object' &&
|
||||
child.props &&
|
||||
child.type === IonTabButton
|
||||
) {
|
||||
tabs[child.props.tab] = {
|
||||
originalHref: child.props.href,
|
||||
currentHref: child.props.href,
|
||||
originalRouteOptions: child.props.href === props.routeInfo?.pathname ? props.routeInfo?.routeOptions : undefined,
|
||||
currentRouteOptions: child.props.href === props.routeInfo?.pathname ? props.routeInfo?.routeOptions : undefined,
|
||||
originalRouteOptions:
|
||||
child.props.href === props.routeInfo?.pathname
|
||||
? props.routeInfo?.routeOptions
|
||||
: undefined,
|
||||
currentRouteOptions:
|
||||
child.props.href === props.routeInfo?.pathname
|
||||
? props.routeInfo?.routeOptions
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
this.state = {
|
||||
tabs
|
||||
tabs,
|
||||
};
|
||||
|
||||
this.onTabButtonClick = this.onTabButtonClick.bind(this);
|
||||
@@ -64,15 +76,14 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
componentDidMount() {
|
||||
const tabs = this.state.tabs;
|
||||
const tabKeys = Object.keys(tabs);
|
||||
const activeTab = tabKeys
|
||||
.find(key => {
|
||||
const href = tabs[key].originalHref;
|
||||
return this.props.routeInfo!.pathname.startsWith(href);
|
||||
});
|
||||
const activeTab = tabKeys.find((key) => {
|
||||
const href = tabs[key].originalHref;
|
||||
return this.props.routeInfo!.pathname.startsWith(href);
|
||||
});
|
||||
|
||||
if (activeTab) {
|
||||
this.setState({
|
||||
activeTab
|
||||
activeTab,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -83,19 +94,21 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
}
|
||||
}
|
||||
|
||||
setActiveTabOnContext = (_tab: string) => { };
|
||||
setActiveTabOnContext = (_tab: string) => {};
|
||||
|
||||
selectTab(tab: string) {
|
||||
const tabUrl = this.state.tabs[tab];
|
||||
if (tabUrl) {
|
||||
this.onTabButtonClick(new CustomEvent('ionTabButtonClick', {
|
||||
detail: {
|
||||
href: tabUrl.currentHref,
|
||||
tab,
|
||||
selected: tab === this.state.activeTab,
|
||||
routeOptions: undefined
|
||||
}
|
||||
}));
|
||||
this.onTabButtonClick(
|
||||
new CustomEvent('ionTabButtonClick', {
|
||||
detail: {
|
||||
href: tabUrl.currentHref,
|
||||
tab,
|
||||
selected: tab === this.state.activeTab,
|
||||
routeOptions: undefined,
|
||||
},
|
||||
})
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -104,22 +117,26 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
static getDerivedStateFromProps(props: InternalProps, state: IonTabBarState) {
|
||||
const tabs = { ...state.tabs };
|
||||
const tabKeys = Object.keys(state.tabs);
|
||||
const activeTab = tabKeys
|
||||
.find(key => {
|
||||
const href = state.tabs[key].originalHref;
|
||||
return props.routeInfo!.pathname.startsWith(href);
|
||||
});
|
||||
const activeTab = tabKeys.find((key) => {
|
||||
const href = state.tabs[key].originalHref;
|
||||
return props.routeInfo!.pathname.startsWith(href);
|
||||
});
|
||||
|
||||
// Check to see if the tab button href has changed, and if so, update it in the tabs state
|
||||
React.Children.forEach((props as any).children, (child: any) => {
|
||||
if (child != null && typeof child === 'object' && child.props && child.type === IonTabButton) {
|
||||
if (
|
||||
child != null &&
|
||||
typeof child === 'object' &&
|
||||
child.props &&
|
||||
child.type === IonTabButton
|
||||
) {
|
||||
const tab = tabs[child.props.tab];
|
||||
if (!tab || (tab.originalHref !== child.props.href)) {
|
||||
if (!tab || tab.originalHref !== child.props.href) {
|
||||
tabs[child.props.tab] = {
|
||||
originalHref: child.props.href,
|
||||
currentHref: child.props.href,
|
||||
originalRouteOptions: child.props.routeOptions,
|
||||
currentRouteOptions: child.props.routeOptions
|
||||
currentRouteOptions: child.props.routeOptions,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -129,20 +146,24 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
if (activeTab && prevActiveTab) {
|
||||
const prevHref = state.tabs[prevActiveTab].currentHref;
|
||||
const prevRouteOptions = state.tabs[prevActiveTab].currentRouteOptions;
|
||||
if (activeTab !== prevActiveTab || (prevHref !== props.routeInfo?.pathname || prevRouteOptions !== props.routeInfo?.routeOptions)) {
|
||||
if (
|
||||
activeTab !== prevActiveTab ||
|
||||
prevHref !== props.routeInfo?.pathname ||
|
||||
prevRouteOptions !== props.routeInfo?.routeOptions
|
||||
) {
|
||||
tabs[activeTab] = {
|
||||
originalHref: tabs[activeTab].originalHref,
|
||||
currentHref: props.routeInfo!.pathname + (props.routeInfo!.search || ''),
|
||||
originalRouteOptions: tabs[activeTab].originalRouteOptions,
|
||||
currentRouteOptions: props.routeInfo?.routeOptions
|
||||
currentRouteOptions: props.routeInfo?.routeOptions,
|
||||
};
|
||||
if (props.routeInfo.routeAction === 'pop' && (activeTab !== prevActiveTab)) {
|
||||
if (props.routeInfo.routeAction === 'pop' && activeTab !== prevActiveTab) {
|
||||
// If navigating back and the tabs change, set the prev tab back to its original href
|
||||
tabs[prevActiveTab] = {
|
||||
originalHref: tabs[prevActiveTab].originalHref,
|
||||
currentHref: tabs[prevActiveTab].originalHref,
|
||||
originalRouteOptions: tabs[prevActiveTab].originalRouteOptions,
|
||||
currentRouteOptions: tabs[prevActiveTab].currentRouteOptions
|
||||
currentRouteOptions: tabs[prevActiveTab].currentRouteOptions,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -152,11 +173,13 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
|
||||
return {
|
||||
activeTab,
|
||||
tabs
|
||||
tabs,
|
||||
};
|
||||
}
|
||||
|
||||
private onTabButtonClick(e: CustomEvent<{ href: string, selected: boolean, tab: string; routeOptions: unknown; }>) {
|
||||
private onTabButtonClick(
|
||||
e: CustomEvent<{ href: string; selected: boolean; tab: string; routeOptions: unknown }>
|
||||
) {
|
||||
const tappedTab = this.state.tabs[e.detail.tab];
|
||||
const originalHref = tappedTab.originalHref;
|
||||
const currentHref = e.detail.href;
|
||||
@@ -169,10 +192,14 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
}
|
||||
} else {
|
||||
if (this.props.onIonTabsWillChange) {
|
||||
this.props.onIonTabsWillChange(new CustomEvent('ionTabWillChange', { detail: { tab: e.detail.tab } }));
|
||||
this.props.onIonTabsWillChange(
|
||||
new CustomEvent('ionTabWillChange', { detail: { tab: e.detail.tab } })
|
||||
);
|
||||
}
|
||||
if (this.props.onIonTabsDidChange) {
|
||||
this.props.onIonTabsDidChange(new CustomEvent('ionTabDidChange', { detail: { tab: e.detail.tab } }));
|
||||
this.props.onIonTabsDidChange(
|
||||
new CustomEvent('ionTabDidChange', { detail: { tab: e.detail.tab } })
|
||||
);
|
||||
}
|
||||
this.setActiveTabOnContext(e.detail.tab);
|
||||
this.context.changeTab(e.detail.tab, currentHref, e.detail.routeOptions);
|
||||
@@ -180,16 +207,28 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
}
|
||||
|
||||
private renderTabButton(activeTab: string | null | undefined) {
|
||||
|
||||
return (child: (React.ReactElement<LocalJSX.IonTabButton & { onClick: (e: any) => void; routeOptions?: unknown; }>) | null | undefined) => {
|
||||
return (
|
||||
child:
|
||||
| React.ReactElement<
|
||||
LocalJSX.IonTabButton & { onClick: (e: any) => void; routeOptions?: unknown }
|
||||
>
|
||||
| null
|
||||
| undefined
|
||||
) => {
|
||||
if (child != null && child.props && child.type === IonTabButton) {
|
||||
const href = (child.props.tab === activeTab) ? this.props.routeInfo?.pathname : (this.state.tabs[child.props.tab!].currentHref);
|
||||
const routeOptions = (child.props.tab === activeTab) ? this.props.routeInfo?.routeOptions : (this.state.tabs[child.props.tab!].currentRouteOptions);
|
||||
const href =
|
||||
child.props.tab === activeTab
|
||||
? this.props.routeInfo?.pathname
|
||||
: this.state.tabs[child.props.tab!].currentHref;
|
||||
const routeOptions =
|
||||
child.props.tab === activeTab
|
||||
? this.props.routeInfo?.routeOptions
|
||||
: this.state.tabs[child.props.tab!].currentRouteOptions;
|
||||
|
||||
return React.cloneElement(child, {
|
||||
href,
|
||||
routeOptions,
|
||||
onClick: this.onTabButtonClick
|
||||
onClick: this.onTabButtonClick,
|
||||
});
|
||||
}
|
||||
return null;
|
||||
@@ -210,18 +249,23 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
|
||||
}
|
||||
}
|
||||
|
||||
const IonTabBarContainer: React.FC<InternalProps> = React.memo<InternalProps>(({ forwardedRef, ...props }) => {
|
||||
const context = useContext(NavContext);
|
||||
return (
|
||||
<IonTabBarUnwrapped
|
||||
ref={forwardedRef}
|
||||
{...props as any}
|
||||
routeInfo={props.routeInfo || context.routeInfo || { pathname: window.location.pathname }}
|
||||
onSetCurrentTab={context.setCurrentTab}
|
||||
>
|
||||
{props.children}
|
||||
</IonTabBarUnwrapped>
|
||||
);
|
||||
});
|
||||
const IonTabBarContainer: React.FC<InternalProps> = React.memo<InternalProps>(
|
||||
({ forwardedRef, ...props }) => {
|
||||
const context = useContext(NavContext);
|
||||
return (
|
||||
<IonTabBarUnwrapped
|
||||
ref={forwardedRef}
|
||||
{...(props as any)}
|
||||
routeInfo={props.routeInfo || context.routeInfo || { pathname: window.location.pathname }}
|
||||
onSetCurrentTab={context.setCurrentTab}
|
||||
>
|
||||
{props.children}
|
||||
</IonTabBarUnwrapped>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const IonTabBar = createForwardRef<IonTabBarProps, HTMLIonTabBarElement>(IonTabBarContainer, 'IonTabBar');
|
||||
export const IonTabBar = createForwardRef<IonTabBarProps, HTMLIonTabBarElement>(
|
||||
IonTabBarContainer,
|
||||
'IonTabBar'
|
||||
);
|
||||
|
||||
@@ -5,14 +5,14 @@ import { RouterOptions } from '../../models';
|
||||
import { IonicReactProps } from '../IonicReactProps';
|
||||
import { IonTabButtonInner } from '../inner-proxies';
|
||||
|
||||
type Props = LocalJSX.IonTabButton & IonicReactProps & {
|
||||
routerOptions?: RouterOptions;
|
||||
ref?: React.RefObject<HTMLIonTabButtonElement>;
|
||||
onClick?: (e: any) => void;
|
||||
};
|
||||
type Props = LocalJSX.IonTabButton &
|
||||
IonicReactProps & {
|
||||
routerOptions?: RouterOptions;
|
||||
ref?: React.RefObject<HTMLIonTabButtonElement>;
|
||||
onClick?: (e: any) => void;
|
||||
};
|
||||
|
||||
export class IonTabButton extends React.Component<Props> {
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.handleIonTabButtonClick = this.handleIonTabButtonClick.bind(this);
|
||||
@@ -20,16 +20,25 @@ export class IonTabButton extends React.Component<Props> {
|
||||
|
||||
handleIonTabButtonClick() {
|
||||
if (this.props.onClick) {
|
||||
this.props.onClick(new CustomEvent('ionTabButtonClick', {
|
||||
detail: { tab: this.props.tab, href: this.props.href, routeOptions: this.props.routerOptions }
|
||||
}));
|
||||
this.props.onClick(
|
||||
new CustomEvent('ionTabButtonClick', {
|
||||
detail: {
|
||||
tab: this.props.tab,
|
||||
href: this.props.href,
|
||||
routeOptions: this.props.routerOptions,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { onClick, ...rest } = this.props;
|
||||
return (
|
||||
<IonTabButtonInner onIonTabButtonClick={this.handleIonTabButtonClick} {...rest}></IonTabButtonInner>
|
||||
<IonTabButtonInner
|
||||
onIonTabButtonClick={this.handleIonTabButtonClick}
|
||||
{...rest}
|
||||
></IonTabButtonInner>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,13 +46,13 @@ const hostStyles: React.CSSProperties = {
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
contain: 'layout size style'
|
||||
contain: 'layout size style',
|
||||
};
|
||||
|
||||
const tabsInner: React.CSSProperties = {
|
||||
position: 'relative',
|
||||
flex: 1,
|
||||
contain: 'layout size style'
|
||||
contain: 'layout size style',
|
||||
};
|
||||
|
||||
export class IonTabs extends React.Component<Props> {
|
||||
@@ -63,7 +63,7 @@ export class IonTabs extends React.Component<Props> {
|
||||
|
||||
ionTabContextState: IonTabsContextState = {
|
||||
activeTab: undefined,
|
||||
selectTab: () => false
|
||||
selectTab: () => false,
|
||||
};
|
||||
|
||||
constructor(props: Props) {
|
||||
@@ -86,8 +86,10 @@ export class IonTabs extends React.Component<Props> {
|
||||
let outlet: React.ReactElement<{}> | undefined;
|
||||
let tabBar: React.ReactElement | undefined;
|
||||
|
||||
const children = typeof this.props.children === 'function' ?
|
||||
(this.props.children as ChildFunction)(this.ionTabContextState) : this.props.children;
|
||||
const children =
|
||||
typeof this.props.children === 'function'
|
||||
? (this.props.children as ChildFunction)(this.ionTabContextState)
|
||||
: this.props.children;
|
||||
|
||||
React.Children.forEach(children, (child: any) => {
|
||||
if (child == null || typeof child !== 'object' || !child.hasOwnProperty('type')) {
|
||||
@@ -103,14 +105,14 @@ export class IonTabs extends React.Component<Props> {
|
||||
tabBar = React.cloneElement(child, {
|
||||
onIonTabsDidChange,
|
||||
onIonTabsWillChange,
|
||||
ref: this.tabBarRef
|
||||
ref: this.tabBarRef,
|
||||
});
|
||||
} else if (child.type === Fragment && child.props.children[1].type === IonTabBar) {
|
||||
const { onIonTabsDidChange, onIonTabsWillChange } = this.props;
|
||||
tabBar = React.cloneElement(child.props.children[1], {
|
||||
onIonTabsDidChange,
|
||||
onIonTabsWillChange,
|
||||
ref: this.tabBarRef
|
||||
ref: this.tabBarRef,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -125,11 +127,13 @@ export class IonTabs extends React.Component<Props> {
|
||||
const { className, ...props } = this.props;
|
||||
|
||||
return (
|
||||
<IonTabsContext.Provider
|
||||
value={this.ionTabContextState}
|
||||
>
|
||||
<IonTabsContext.Provider value={this.ionTabContextState}>
|
||||
{this.context.hasIonicRouter() ? (
|
||||
<PageManager className={className ? `${className}` : ''} routeInfo={this.context.routeInfo} {...props}>
|
||||
<PageManager
|
||||
className={className ? `${className}` : ''}
|
||||
routeInfo={this.context.routeInfo}
|
||||
{...props}
|
||||
>
|
||||
<ion-tabs className="ion-tabs" style={hostStyles}>
|
||||
{tabBar.props.slot === 'top' ? tabBar : null}
|
||||
<div style={tabsInner} className="tabs-inner">
|
||||
@@ -139,15 +143,15 @@ export class IonTabs extends React.Component<Props> {
|
||||
</ion-tabs>
|
||||
</PageManager>
|
||||
) : (
|
||||
<div className={className ? `${className}` : 'ion-tabs'} {...props} style={hostStyles}>
|
||||
{tabBar.props.slot === 'top' ? tabBar : null}
|
||||
<div style={tabsInner} className="tabs-inner">
|
||||
{outlet}
|
||||
</div>
|
||||
{tabBar.props.slot === 'bottom' ? tabBar : null}
|
||||
<div className={className ? `${className}` : 'ion-tabs'} {...props} style={hostStyles}>
|
||||
{tabBar.props.slot === 'top' ? tabBar : null}
|
||||
<div style={tabsInner} className="tabs-inner">
|
||||
{outlet}
|
||||
</div>
|
||||
)}
|
||||
</IonTabsContext.Provider >
|
||||
{tabBar.props.slot === 'bottom' ? tabBar : null}
|
||||
</div>
|
||||
)}
|
||||
</IonTabsContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,5 +7,5 @@ export interface IonTabsContextState {
|
||||
|
||||
export const IonTabsContext = React.createContext<IonTabsContextState>({
|
||||
activeTab: undefined,
|
||||
selectTab: () => false
|
||||
selectTab: () => false,
|
||||
});
|
||||
|
||||
@@ -4,74 +4,240 @@ import { createReactComponent } from './createComponent';
|
||||
import { HrefProps } from './hrefprops';
|
||||
|
||||
// ionic/core
|
||||
export const IonApp = /*@__PURE__*/createReactComponent<JSX.IonApp, HTMLIonAppElement>('ion-app');
|
||||
export const IonTab = /*@__PURE__*/createReactComponent<JSX.IonTab, HTMLIonTabElement>('ion-tab');
|
||||
export const IonRouterLink = /*@__PURE__*/createReactComponent<HrefProps<JSX.IonRouterLink>, HTMLIonRouterLinkElement>('ion-router-link', true);
|
||||
export const IonAvatar = /*@__PURE__*/createReactComponent<JSX.IonAvatar, HTMLIonAvatarElement>('ion-avatar');
|
||||
export const IonBackdrop = /*@__PURE__*/createReactComponent<JSX.IonBackdrop, HTMLIonBackdropElement>('ion-backdrop');
|
||||
export const IonBadge = /*@__PURE__*/createReactComponent<JSX.IonBadge, HTMLIonBadgeElement>('ion-badge');
|
||||
export const IonButton = /*@__PURE__*/createReactComponent<HrefProps<JSX.IonButton>, HTMLIonButtonElement>('ion-button', true);
|
||||
export const IonButtons = /*@__PURE__*/createReactComponent<JSX.IonButtons, HTMLIonButtonsElement>('ion-buttons');
|
||||
export const IonCard = /*@__PURE__*/createReactComponent<HrefProps<JSX.IonCard>, HTMLIonCardElement>('ion-card', true);
|
||||
export const IonCardContent = /*@__PURE__*/createReactComponent<JSX.IonCardContent, HTMLIonCardContentElement>('ion-card-content');
|
||||
export const IonCardHeader = /*@__PURE__*/createReactComponent<JSX.IonCardHeader, HTMLIonCardHeaderElement>('ion-card-header');
|
||||
export const IonCardSubtitle = /*@__PURE__*/createReactComponent<JSX.IonCardSubtitle, HTMLIonCardSubtitleElement>('ion-card-subtitle');
|
||||
export const IonCardTitle = /*@__PURE__*/createReactComponent<JSX.IonCardTitle, HTMLIonCardTitleElement>('ion-card-title');
|
||||
export const IonCheckbox = /*@__PURE__*/createReactComponent<JSX.IonCheckbox, HTMLIonCheckboxElement>('ion-checkbox');
|
||||
export const IonCol = /*@__PURE__*/createReactComponent<JSX.IonCol, HTMLIonColElement>('ion-col');
|
||||
export const IonContent = /*@__PURE__*/createReactComponent<JSX.IonContent, HTMLIonContentElement>('ion-content');
|
||||
export const IonChip = /*@__PURE__*/createReactComponent<JSX.IonChip, HTMLIonChipElement>('ion-chip');
|
||||
export const IonDatetime = /*@__PURE__*/createReactComponent<JSX.IonDatetime, HTMLIonDatetimeElement>('ion-datetime');
|
||||
export const IonFab = /*@__PURE__*/createReactComponent<JSX.IonFab, HTMLIonFabElement>('ion-fab');
|
||||
export const IonFabButton = /*@__PURE__*/createReactComponent<HrefProps<JSX.IonFabButton>, HTMLIonFabButtonElement>('ion-fab-button', true);
|
||||
export const IonFabList = /*@__PURE__*/createReactComponent<JSX.IonFabList, HTMLIonFabListElement>('ion-fab-list');
|
||||
export const IonFooter = /*@__PURE__*/createReactComponent<JSX.IonFooter, HTMLIonFooterElement>('ion-footer');
|
||||
export const IonGrid = /*@__PURE__*/createReactComponent<JSX.IonGrid, HTMLIonGridElement>('ion-grid');
|
||||
export const IonHeader = /*@__PURE__*/createReactComponent<JSX.IonHeader, HTMLIonHeaderElement>('ion-header');
|
||||
export const IonImg = /*@__PURE__*/createReactComponent<JSX.IonImg, HTMLIonImgElement>('ion-img');
|
||||
export const IonInfiniteScroll = /*@__PURE__*/createReactComponent<JSX.IonInfiniteScroll, HTMLIonInfiniteScrollElement>('ion-infinite-scroll');
|
||||
export const IonInfiniteScrollContent = /*@__PURE__*/createReactComponent<JSX.IonInfiniteScrollContent, HTMLIonInfiniteScrollContentElement>('ion-infinite-scroll-content');
|
||||
export const IonInput = /*@__PURE__*/createReactComponent<JSX.IonInput, HTMLIonInputElement>('ion-input');
|
||||
export const IonItem = /*@__PURE__*/createReactComponent<HrefProps<JSX.IonItem>, HTMLIonItemElement>('ion-item', true);
|
||||
export const IonItemDivider = /*@__PURE__*/createReactComponent<JSX.IonItemDivider, HTMLIonItemDividerElement>('ion-item-divider');
|
||||
export const IonItemGroup = /*@__PURE__*/createReactComponent<JSX.IonItemGroup, HTMLIonItemGroupElement>('ion-item-group');
|
||||
export const IonItemOption = /*@__PURE__*/createReactComponent<HrefProps<JSX.IonItemOption>, HTMLIonItemOptionElement>('ion-item-option', true);
|
||||
export const IonItemOptions = /*@__PURE__*/createReactComponent<JSX.IonItemOptions, HTMLIonItemOptionsElement>('ion-item-options');
|
||||
export const IonItemSliding = /*@__PURE__*/createReactComponent<JSX.IonItemSliding, HTMLIonItemSlidingElement>('ion-item-sliding');
|
||||
export const IonLabel = /*@__PURE__*/createReactComponent<JSX.IonLabel, HTMLIonLabelElement>('ion-label');
|
||||
export const IonList = /*@__PURE__*/createReactComponent<JSX.IonList, HTMLIonListElement>('ion-list');
|
||||
export const IonListHeader = /*@__PURE__*/createReactComponent<JSX.IonListHeader, HTMLIonListHeaderElement>('ion-list-header');
|
||||
export const IonMenu = /*@__PURE__*/createReactComponent<JSX.IonMenu, HTMLIonMenuElement>('ion-menu');
|
||||
export const IonMenuButton = /*@__PURE__*/createReactComponent<JSX.IonMenuButton, HTMLIonMenuButtonElement>('ion-menu-button');
|
||||
export const IonMenuToggle = /*@__PURE__*/createReactComponent<JSX.IonMenuToggle, HTMLIonMenuToggleElement>('ion-menu-toggle');
|
||||
export const IonNote = /*@__PURE__*/createReactComponent<JSX.IonNote, HTMLIonNoteElement>('ion-note');
|
||||
export const IonPickerColumn = /*@__PURE__*/createReactComponent<JSX.IonPickerColumn, HTMLIonPickerColumnElement>('ion-picker-column');
|
||||
export const IonNav = /*@__PURE__*/createReactComponent<JSX.IonNav, HTMLIonNavElement>('ion-nav');
|
||||
export const IonProgressBar = /*@__PURE__*/createReactComponent<JSX.IonProgressBar, HTMLIonProgressBarElement>('ion-progress-bar');
|
||||
export const IonRadio = /*@__PURE__*/createReactComponent<JSX.IonRadio, HTMLIonRadioElement>('ion-radio');
|
||||
export const IonRadioGroup = /*@__PURE__*/createReactComponent<JSX.IonRadioGroup, HTMLIonRadioGroupElement>('ion-radio-group');
|
||||
export const IonRange = /*@__PURE__*/createReactComponent<JSX.IonRange, HTMLIonRangeElement>('ion-range');
|
||||
export const IonRefresher = /*@__PURE__*/createReactComponent<JSX.IonRefresher, HTMLIonRefresherElement>('ion-refresher');
|
||||
export const IonRefresherContent = /*@__PURE__*/createReactComponent<JSX.IonRefresherContent, HTMLIonRefresherContentElement>('ion-refresher-content');
|
||||
export const IonReorder = /*@__PURE__*/createReactComponent<JSX.IonReorder, HTMLIonReorderElement>('ion-reorder');
|
||||
export const IonReorderGroup = /*@__PURE__*/createReactComponent<JSX.IonReorderGroup, HTMLIonReorderGroupElement>('ion-reorder-group');
|
||||
export const IonRippleEffect = /*@__PURE__*/createReactComponent<JSX.IonRippleEffect, HTMLIonRippleEffectElement>('ion-ripple-effect');
|
||||
export const IonRow = /*@__PURE__*/createReactComponent<JSX.IonRow, HTMLIonRowElement>('ion-row');
|
||||
export const IonSearchbar = /*@__PURE__*/createReactComponent<JSX.IonSearchbar, HTMLIonSearchbarElement>('ion-searchbar');
|
||||
export const IonSegment = /*@__PURE__*/createReactComponent<JSX.IonSegment, HTMLIonSegmentElement>('ion-segment');
|
||||
export const IonSegmentButton = /*@__PURE__*/createReactComponent<JSX.IonSegmentButton, HTMLIonSegmentButtonElement>('ion-segment-button');
|
||||
export const IonSelect = /*@__PURE__*/createReactComponent<JSX.IonSelect, HTMLIonSelectElement>('ion-select');
|
||||
export const IonSelectOption = /*@__PURE__*/createReactComponent<JSX.IonSelectOption, HTMLIonSelectOptionElement>('ion-select-option');
|
||||
export const IonSelectPopover = /*@__PURE__*/createReactComponent<JSX.IonSelectPopover, HTMLIonSelectPopoverElement>('ion-select-popover');
|
||||
export const IonSkeletonText = /*@__PURE__*/createReactComponent<JSX.IonSkeletonText, HTMLIonSkeletonTextElement>('ion-skeleton-text');
|
||||
export const IonSlide = /*@__PURE__*/createReactComponent<JSX.IonSlide, HTMLIonSlideElement>('ion-slide');
|
||||
export const IonSlides = /*@__PURE__*/createReactComponent<JSX.IonSlides, HTMLIonSlidesElement>('ion-slides');
|
||||
export const IonSpinner = /*@__PURE__*/createReactComponent<JSX.IonSpinner, HTMLIonSpinnerElement>('ion-spinner');
|
||||
export const IonSplitPane = /*@__PURE__*/createReactComponent<JSX.IonSplitPane, HTMLIonSplitPaneElement>('ion-split-pane');
|
||||
export const IonText = /*@__PURE__*/createReactComponent<JSX.IonText, HTMLIonTextElement>('ion-text');
|
||||
export const IonTextarea = /*@__PURE__*/createReactComponent<JSX.IonTextarea, HTMLIonTextareaElement>('ion-textarea');
|
||||
export const IonThumbnail = /*@__PURE__*/createReactComponent<JSX.IonThumbnail, HTMLIonThumbnailElement>('ion-thumbnail');
|
||||
export const IonTitle = /*@__PURE__*/createReactComponent<JSX.IonTitle, HTMLIonTitleElement>('ion-title');
|
||||
export const IonToggle = /*@__PURE__*/createReactComponent<JSX.IonToggle, HTMLIonToggleElement>('ion-toggle');
|
||||
export const IonToolbar = /*@__PURE__*/createReactComponent<JSX.IonToolbar, HTMLIonToolbarElement>('ion-toolbar');
|
||||
export const IonVirtualScroll = /*@__PURE__*/createReactComponent<JSX.IonVirtualScroll, HTMLIonVirtualScrollElement>('ion-virtual-scroll');
|
||||
export const IonApp = /*@__PURE__*/ createReactComponent<JSX.IonApp, HTMLIonAppElement>('ion-app');
|
||||
export const IonTab = /*@__PURE__*/ createReactComponent<JSX.IonTab, HTMLIonTabElement>('ion-tab');
|
||||
export const IonRouterLink = /*@__PURE__*/ createReactComponent<
|
||||
HrefProps<JSX.IonRouterLink>,
|
||||
HTMLIonRouterLinkElement
|
||||
>('ion-router-link', true);
|
||||
export const IonAvatar = /*@__PURE__*/ createReactComponent<JSX.IonAvatar, HTMLIonAvatarElement>(
|
||||
'ion-avatar'
|
||||
);
|
||||
export const IonBackdrop = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonBackdrop,
|
||||
HTMLIonBackdropElement
|
||||
>('ion-backdrop');
|
||||
export const IonBadge = /*@__PURE__*/ createReactComponent<JSX.IonBadge, HTMLIonBadgeElement>(
|
||||
'ion-badge'
|
||||
);
|
||||
export const IonButton = /*@__PURE__*/ createReactComponent<
|
||||
HrefProps<JSX.IonButton>,
|
||||
HTMLIonButtonElement
|
||||
>('ion-button', true);
|
||||
export const IonButtons = /*@__PURE__*/ createReactComponent<JSX.IonButtons, HTMLIonButtonsElement>(
|
||||
'ion-buttons'
|
||||
);
|
||||
export const IonCard = /*@__PURE__*/ createReactComponent<
|
||||
HrefProps<JSX.IonCard>,
|
||||
HTMLIonCardElement
|
||||
>('ion-card', true);
|
||||
export const IonCardContent = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonCardContent,
|
||||
HTMLIonCardContentElement
|
||||
>('ion-card-content');
|
||||
export const IonCardHeader = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonCardHeader,
|
||||
HTMLIonCardHeaderElement
|
||||
>('ion-card-header');
|
||||
export const IonCardSubtitle = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonCardSubtitle,
|
||||
HTMLIonCardSubtitleElement
|
||||
>('ion-card-subtitle');
|
||||
export const IonCardTitle = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonCardTitle,
|
||||
HTMLIonCardTitleElement
|
||||
>('ion-card-title');
|
||||
export const IonCheckbox = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonCheckbox,
|
||||
HTMLIonCheckboxElement
|
||||
>('ion-checkbox');
|
||||
export const IonCol = /*@__PURE__*/ createReactComponent<JSX.IonCol, HTMLIonColElement>('ion-col');
|
||||
export const IonContent = /*@__PURE__*/ createReactComponent<JSX.IonContent, HTMLIonContentElement>(
|
||||
'ion-content'
|
||||
);
|
||||
export const IonChip = /*@__PURE__*/ createReactComponent<JSX.IonChip, HTMLIonChipElement>(
|
||||
'ion-chip'
|
||||
);
|
||||
export const IonDatetime = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonDatetime,
|
||||
HTMLIonDatetimeElement
|
||||
>('ion-datetime');
|
||||
export const IonFab = /*@__PURE__*/ createReactComponent<JSX.IonFab, HTMLIonFabElement>('ion-fab');
|
||||
export const IonFabButton = /*@__PURE__*/ createReactComponent<
|
||||
HrefProps<JSX.IonFabButton>,
|
||||
HTMLIonFabButtonElement
|
||||
>('ion-fab-button', true);
|
||||
export const IonFabList = /*@__PURE__*/ createReactComponent<JSX.IonFabList, HTMLIonFabListElement>(
|
||||
'ion-fab-list'
|
||||
);
|
||||
export const IonFooter = /*@__PURE__*/ createReactComponent<JSX.IonFooter, HTMLIonFooterElement>(
|
||||
'ion-footer'
|
||||
);
|
||||
export const IonGrid = /*@__PURE__*/ createReactComponent<JSX.IonGrid, HTMLIonGridElement>(
|
||||
'ion-grid'
|
||||
);
|
||||
export const IonHeader = /*@__PURE__*/ createReactComponent<JSX.IonHeader, HTMLIonHeaderElement>(
|
||||
'ion-header'
|
||||
);
|
||||
export const IonImg = /*@__PURE__*/ createReactComponent<JSX.IonImg, HTMLIonImgElement>('ion-img');
|
||||
export const IonInfiniteScroll = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonInfiniteScroll,
|
||||
HTMLIonInfiniteScrollElement
|
||||
>('ion-infinite-scroll');
|
||||
export const IonInfiniteScrollContent = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonInfiniteScrollContent,
|
||||
HTMLIonInfiniteScrollContentElement
|
||||
>('ion-infinite-scroll-content');
|
||||
export const IonInput = /*@__PURE__*/ createReactComponent<JSX.IonInput, HTMLIonInputElement>(
|
||||
'ion-input'
|
||||
);
|
||||
export const IonItem = /*@__PURE__*/ createReactComponent<
|
||||
HrefProps<JSX.IonItem>,
|
||||
HTMLIonItemElement
|
||||
>('ion-item', true);
|
||||
export const IonItemDivider = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonItemDivider,
|
||||
HTMLIonItemDividerElement
|
||||
>('ion-item-divider');
|
||||
export const IonItemGroup = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonItemGroup,
|
||||
HTMLIonItemGroupElement
|
||||
>('ion-item-group');
|
||||
export const IonItemOption = /*@__PURE__*/ createReactComponent<
|
||||
HrefProps<JSX.IonItemOption>,
|
||||
HTMLIonItemOptionElement
|
||||
>('ion-item-option', true);
|
||||
export const IonItemOptions = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonItemOptions,
|
||||
HTMLIonItemOptionsElement
|
||||
>('ion-item-options');
|
||||
export const IonItemSliding = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonItemSliding,
|
||||
HTMLIonItemSlidingElement
|
||||
>('ion-item-sliding');
|
||||
export const IonLabel = /*@__PURE__*/ createReactComponent<JSX.IonLabel, HTMLIonLabelElement>(
|
||||
'ion-label'
|
||||
);
|
||||
export const IonList = /*@__PURE__*/ createReactComponent<JSX.IonList, HTMLIonListElement>(
|
||||
'ion-list'
|
||||
);
|
||||
export const IonListHeader = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonListHeader,
|
||||
HTMLIonListHeaderElement
|
||||
>('ion-list-header');
|
||||
export const IonMenu = /*@__PURE__*/ createReactComponent<JSX.IonMenu, HTMLIonMenuElement>(
|
||||
'ion-menu'
|
||||
);
|
||||
export const IonMenuButton = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonMenuButton,
|
||||
HTMLIonMenuButtonElement
|
||||
>('ion-menu-button');
|
||||
export const IonMenuToggle = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonMenuToggle,
|
||||
HTMLIonMenuToggleElement
|
||||
>('ion-menu-toggle');
|
||||
export const IonNote = /*@__PURE__*/ createReactComponent<JSX.IonNote, HTMLIonNoteElement>(
|
||||
'ion-note'
|
||||
);
|
||||
export const IonPickerColumn = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonPickerColumn,
|
||||
HTMLIonPickerColumnElement
|
||||
>('ion-picker-column');
|
||||
export const IonNav = /*@__PURE__*/ createReactComponent<JSX.IonNav, HTMLIonNavElement>('ion-nav');
|
||||
export const IonProgressBar = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonProgressBar,
|
||||
HTMLIonProgressBarElement
|
||||
>('ion-progress-bar');
|
||||
export const IonRadio = /*@__PURE__*/ createReactComponent<JSX.IonRadio, HTMLIonRadioElement>(
|
||||
'ion-radio'
|
||||
);
|
||||
export const IonRadioGroup = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonRadioGroup,
|
||||
HTMLIonRadioGroupElement
|
||||
>('ion-radio-group');
|
||||
export const IonRange = /*@__PURE__*/ createReactComponent<JSX.IonRange, HTMLIonRangeElement>(
|
||||
'ion-range'
|
||||
);
|
||||
export const IonRefresher = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonRefresher,
|
||||
HTMLIonRefresherElement
|
||||
>('ion-refresher');
|
||||
export const IonRefresherContent = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonRefresherContent,
|
||||
HTMLIonRefresherContentElement
|
||||
>('ion-refresher-content');
|
||||
export const IonReorder = /*@__PURE__*/ createReactComponent<JSX.IonReorder, HTMLIonReorderElement>(
|
||||
'ion-reorder'
|
||||
);
|
||||
export const IonReorderGroup = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonReorderGroup,
|
||||
HTMLIonReorderGroupElement
|
||||
>('ion-reorder-group');
|
||||
export const IonRippleEffect = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonRippleEffect,
|
||||
HTMLIonRippleEffectElement
|
||||
>('ion-ripple-effect');
|
||||
export const IonRow = /*@__PURE__*/ createReactComponent<JSX.IonRow, HTMLIonRowElement>('ion-row');
|
||||
export const IonSearchbar = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonSearchbar,
|
||||
HTMLIonSearchbarElement
|
||||
>('ion-searchbar');
|
||||
export const IonSegment = /*@__PURE__*/ createReactComponent<JSX.IonSegment, HTMLIonSegmentElement>(
|
||||
'ion-segment'
|
||||
);
|
||||
export const IonSegmentButton = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonSegmentButton,
|
||||
HTMLIonSegmentButtonElement
|
||||
>('ion-segment-button');
|
||||
export const IonSelect = /*@__PURE__*/ createReactComponent<JSX.IonSelect, HTMLIonSelectElement>(
|
||||
'ion-select'
|
||||
);
|
||||
export const IonSelectOption = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonSelectOption,
|
||||
HTMLIonSelectOptionElement
|
||||
>('ion-select-option');
|
||||
export const IonSelectPopover = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonSelectPopover,
|
||||
HTMLIonSelectPopoverElement
|
||||
>('ion-select-popover');
|
||||
export const IonSkeletonText = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonSkeletonText,
|
||||
HTMLIonSkeletonTextElement
|
||||
>('ion-skeleton-text');
|
||||
export const IonSlide = /*@__PURE__*/ createReactComponent<JSX.IonSlide, HTMLIonSlideElement>(
|
||||
'ion-slide'
|
||||
);
|
||||
export const IonSlides = /*@__PURE__*/ createReactComponent<JSX.IonSlides, HTMLIonSlidesElement>(
|
||||
'ion-slides'
|
||||
);
|
||||
export const IonSpinner = /*@__PURE__*/ createReactComponent<JSX.IonSpinner, HTMLIonSpinnerElement>(
|
||||
'ion-spinner'
|
||||
);
|
||||
export const IonSplitPane = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonSplitPane,
|
||||
HTMLIonSplitPaneElement
|
||||
>('ion-split-pane');
|
||||
export const IonText = /*@__PURE__*/ createReactComponent<JSX.IonText, HTMLIonTextElement>(
|
||||
'ion-text'
|
||||
);
|
||||
export const IonTextarea = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonTextarea,
|
||||
HTMLIonTextareaElement
|
||||
>('ion-textarea');
|
||||
export const IonThumbnail = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonThumbnail,
|
||||
HTMLIonThumbnailElement
|
||||
>('ion-thumbnail');
|
||||
export const IonTitle = /*@__PURE__*/ createReactComponent<JSX.IonTitle, HTMLIonTitleElement>(
|
||||
'ion-title'
|
||||
);
|
||||
export const IonToggle = /*@__PURE__*/ createReactComponent<JSX.IonToggle, HTMLIonToggleElement>(
|
||||
'ion-toggle'
|
||||
);
|
||||
export const IonToolbar = /*@__PURE__*/ createReactComponent<JSX.IonToolbar, HTMLIonToolbarElement>(
|
||||
'ion-toolbar'
|
||||
);
|
||||
export const IonVirtualScroll = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonVirtualScroll,
|
||||
HTMLIonVirtualScrollElement
|
||||
>('ion-virtual-scroll');
|
||||
|
||||
@@ -9,8 +9,15 @@ export const attachProps = (node: HTMLElement, newProps: any, oldProps: any = {}
|
||||
node.className = className;
|
||||
}
|
||||
|
||||
Object.keys(newProps).forEach(name => {
|
||||
if (name === 'children' || name === 'style' || name === 'ref' || name === 'class' || name === 'className' || name === 'forwardedRef') {
|
||||
Object.keys(newProps).forEach((name) => {
|
||||
if (
|
||||
name === 'children' ||
|
||||
name === 'style' ||
|
||||
name === 'ref' ||
|
||||
name === 'class' ||
|
||||
name === 'className' ||
|
||||
name === 'forwardedRef'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (name.indexOf('on') === 0 && name[2] === name[2].toUpperCase()) {
|
||||
@@ -42,7 +49,7 @@ export const getClassName = (classList: DOMTokenList, newProps: any, oldProps: a
|
||||
const finalClassNames: string[] = [];
|
||||
// loop through each of the current classes on the component
|
||||
// to see if it should be a part of the classNames added
|
||||
currentClasses.forEach(currentClass => {
|
||||
currentClasses.forEach((currentClass) => {
|
||||
if (incomingPropClasses.has(currentClass)) {
|
||||
// add it as its already included in classnames coming in from newProps
|
||||
finalClassNames.push(currentClass);
|
||||
@@ -52,7 +59,7 @@ export const getClassName = (classList: DOMTokenList, newProps: any, oldProps: a
|
||||
finalClassNames.push(currentClass);
|
||||
}
|
||||
});
|
||||
incomingPropClasses.forEach(s => finalClassNames.push(s));
|
||||
incomingPropClasses.forEach((s) => finalClassNames.push(s));
|
||||
return finalClassNames.join(' ');
|
||||
};
|
||||
|
||||
@@ -77,7 +84,11 @@ export const isCoveredByReact = (eventNameSuffix: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const syncEvent = (node: Element & { __events?: { [key: string]: ((e: Event) => any) | undefined; }; }, eventName: string, newEventHandler?: (e: Event) => any) => {
|
||||
export const syncEvent = (
|
||||
node: Element & { __events?: { [key: string]: ((e: Event) => any) | undefined } },
|
||||
eventName: string,
|
||||
newEventHandler?: (e: Event) => any
|
||||
) => {
|
||||
const eventStore = node.__events || (node.__events = {});
|
||||
const oldEventHandler = eventStore[eventName];
|
||||
|
||||
@@ -87,9 +98,14 @@ export const syncEvent = (node: Element & { __events?: { [key: string]: ((e: Eve
|
||||
}
|
||||
|
||||
// Bind new listener.
|
||||
node.addEventListener(eventName, eventStore[eventName] = function handler(e: Event) {
|
||||
if (newEventHandler) { newEventHandler.call(this, e); }
|
||||
});
|
||||
node.addEventListener(
|
||||
eventName,
|
||||
(eventStore[eventName] = function handler(e: Event) {
|
||||
if (newEventHandler) {
|
||||
newEventHandler.call(this, e);
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const arrayToMap = (arr: string[] | DOMTokenList) => {
|
||||
|
||||
@@ -1,2 +1,8 @@
|
||||
export const dashToPascalCase = (str: string) => str.toLowerCase().split('-').map(segment => segment.charAt(0).toUpperCase() + segment.slice(1)).join('');
|
||||
export const camelToDashCase = (str: string) => str.replace(/([A-Z])/g, (m: string) => `-${m[0].toLowerCase()}`);
|
||||
export const dashToPascalCase = (str: string) =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.split('-')
|
||||
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
||||
.join('');
|
||||
export const camelToDashCase = (str: string) =>
|
||||
str.replace(/([A-Z])/g, (m: string) => `-${m[0].toLowerCase()}`);
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
import { Config as CoreConfig, Platforms, getPlatforms as getPlatformsCore, isPlatform as isPlatformCore } from '@ionic/core';
|
||||
import {
|
||||
Config as CoreConfig,
|
||||
Platforms,
|
||||
getPlatforms as getPlatformsCore,
|
||||
isPlatform as isPlatformCore,
|
||||
} from '@ionic/core';
|
||||
import React from 'react';
|
||||
|
||||
import { IonicReactProps } from '../IonicReactProps';
|
||||
|
||||
export type IonicReactExternalProps<PropType, ElementType> = PropType & Omit<React.HTMLAttributes<ElementType>, 'style'> & IonicReactProps;
|
||||
export type IonicReactExternalProps<PropType, ElementType> = PropType &
|
||||
Omit<React.HTMLAttributes<ElementType>, 'style'> &
|
||||
IonicReactProps;
|
||||
|
||||
export const createForwardRef = <PropType, ElementType>(ReactComponent: any, displayName: string) => {
|
||||
const forwardRef = (props: IonicReactExternalProps<PropType, ElementType>, ref: React.Ref<ElementType>) => {
|
||||
export const createForwardRef = <PropType, ElementType>(
|
||||
ReactComponent: any,
|
||||
displayName: string
|
||||
) => {
|
||||
const forwardRef = (
|
||||
props: IonicReactExternalProps<PropType, ElementType>,
|
||||
ref: React.Ref<ElementType>
|
||||
) => {
|
||||
return <ReactComponent {...props} forwardedRef={ref} />;
|
||||
};
|
||||
forwardRef.displayName = displayName;
|
||||
|
||||
@@ -1,36 +1,43 @@
|
||||
import { SerializeDocumentOptions, renderToString } from '@ionic/core/hydrate';
|
||||
|
||||
export async function ionRenderToString(html: string, userAgent: string, options: SerializeDocumentOptions = {}) {
|
||||
export async function ionRenderToString(
|
||||
html: string,
|
||||
userAgent: string,
|
||||
options: SerializeDocumentOptions = {}
|
||||
) {
|
||||
const renderToStringOptions = Object.assign(
|
||||
{},
|
||||
{
|
||||
clientHydrateAnnotations: false,
|
||||
excludeComponents: [
|
||||
// overlays
|
||||
'ion-action-sheet',
|
||||
'ion-alert',
|
||||
'ion-loading',
|
||||
'ion-modal',
|
||||
'ion-picker',
|
||||
'ion-popover',
|
||||
'ion-toast',
|
||||
|
||||
const renderToStringOptions = Object.assign({}, {
|
||||
clientHydrateAnnotations: false,
|
||||
excludeComponents: [
|
||||
// overlays
|
||||
'ion-action-sheet',
|
||||
'ion-alert',
|
||||
'ion-loading',
|
||||
'ion-modal',
|
||||
'ion-picker',
|
||||
'ion-popover',
|
||||
'ion-toast',
|
||||
// navigation
|
||||
'ion-router',
|
||||
'ion-route',
|
||||
'ion-route-redirect',
|
||||
'ion-router-link',
|
||||
'ion-router-outlet',
|
||||
|
||||
// navigation
|
||||
'ion-router',
|
||||
'ion-route',
|
||||
'ion-route-redirect',
|
||||
'ion-router-link',
|
||||
'ion-router-outlet',
|
||||
// tabs
|
||||
'ion-tabs',
|
||||
'ion-tab',
|
||||
|
||||
// tabs
|
||||
'ion-tabs',
|
||||
'ion-tab',
|
||||
|
||||
// auxiliary
|
||||
'ion-picker-column',
|
||||
'ion-virtual-scroll'
|
||||
],
|
||||
userAgent
|
||||
}, options);
|
||||
// auxiliary
|
||||
'ion-picker-column',
|
||||
'ion-virtual-scroll',
|
||||
],
|
||||
userAgent,
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
const ionHtml = await renderToString(html, renderToStringOptions);
|
||||
return ionHtml.html;
|
||||
|
||||
Reference in New Issue
Block a user