feat(react): add custom elements bundle (#23896)

This commit is contained in:
Liam DeBeasi
2021-09-13 14:53:28 -04:00
committed by GitHub
parent d1763fc8b5
commit c50d895370
57 changed files with 321 additions and 565 deletions

View File

@ -6,7 +6,7 @@ import {
AnimationKeyFrames,
AnimationLifecycle,
createAnimation,
} from '@ionic/core';
} from '@ionic/core/components';
import React from 'react';
interface PartialPropertyValue {

View File

@ -2,7 +2,8 @@ import {
ActionSheetButton as ActionSheetButtonCore,
ActionSheetOptions as ActionSheetOptionsCore,
actionSheetController as actionSheetControllerCore,
} from '@ionic/core';
} from '@ionic/core/components';
import { IonActionSheet as IonActionSheetCmp } from '@ionic/core/components/ion-action-sheet.js';
import { createOverlayComponent } from './createOverlayComponent';
@ -29,4 +30,4 @@ const actionSheetController = {
export const IonActionSheet = /*@__PURE__*/ createOverlayComponent<
ActionSheetOptions,
HTMLIonActionSheetElement
>('IonActionSheet', actionSheetController);
>('ion-action-sheet', actionSheetController, IonActionSheetCmp);

View File

@ -1,8 +1,10 @@
import { AlertOptions, alertController } from '@ionic/core';
import { AlertOptions, alertController } from '@ionic/core/components';
import { IonAlert as IonAlertCmp } from '@ionic/core/components/ion-alert.js';
import { createControllerComponent } from './createControllerComponent';
export const IonAlert = /*@__PURE__*/ createControllerComponent<AlertOptions, HTMLIonAlertElement>(
'IonAlert',
alertController
'ion-alert',
alertController,
IonAlertCmp
);

View File

@ -4,7 +4,6 @@ import { NavContext } from '../contexts/NavContext';
import { IonicReactProps } from './IonicReactProps';
import { IonIconInner } from './inner-proxies';
import { deprecationWarning } from './react-component-lib/utils/dev';
import { createForwardRef, isPlatform } from './utils';
interface IonIconProps {
@ -29,10 +28,7 @@ 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.'
);
console.warn('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.');
}
}

View File

@ -1,8 +1,9 @@
import { LoadingOptions, loadingController } from '@ionic/core';
import { LoadingOptions, loadingController } from '@ionic/core/components';
import { IonLoading as IonLoadingCmp } from '@ionic/core/components/ion-loading.js';
import { createControllerComponent } from './createControllerComponent';
export const IonLoading = /*@__PURE__*/ createControllerComponent<
LoadingOptions,
HTMLIonLoadingElement
>('IonLoading', loadingController);
>('ion-loading', loadingController, IonLoadingCmp);

View File

@ -1,8 +1,9 @@
import { JSX } from '@ionic/core';
import { JSX } from '@ionic/core/components';
import { IonModal as IonModalCmp } from '@ionic/core/components/ion-modal.js';
import { createInlineOverlayComponent } from './createInlineOverlayComponent'
export const IonModal = /*@__PURE__*/ createInlineOverlayComponent<
JSX.IonModal,
HTMLIonModalElement
>('ion-modal');
>('ion-modal', IonModalCmp);

View File

@ -1,8 +1,9 @@
import { PickerOptions, pickerController } from '@ionic/core';
import { PickerOptions, pickerController } from '@ionic/core/components';
import { IonPicker as IonPickerCmp } from '@ionic/core/components/ion-picker.js';
import { createControllerComponent } from './createControllerComponent';
export const IonPicker = /*@__PURE__*/ createControllerComponent<
PickerOptions,
HTMLIonPickerElement
>('IonPicker', pickerController);
>('ion-picker', pickerController, IonPickerCmp);

View File

@ -1,8 +1,9 @@
import { JSX } from '@ionic/core';
import { JSX } from '@ionic/core/components';
import { IonPopover as IonPopoverCmp } from '@ionic/core/components/ion-popover.js';
import { createInlineOverlayComponent } from './createInlineOverlayComponent'
export const IonPopover = /*@__PURE__*/ createInlineOverlayComponent<
JSX.IonPopover,
HTMLIonPopoverElement
>('ion-popover');
>('ion-popover', IonPopoverCmp);

View File

@ -1,4 +1,4 @@
import { AnimationBuilder } from '@ionic/core';
import { AnimationBuilder } from '@ionic/core/components';
import React, { useContext } from 'react';
import { RouteAction, RouterDirection, RouterOptions } from '../models';

View File

@ -1,4 +1,4 @@
import { JSX as LocalJSX } from '@ionic/core';
import { JSX as LocalJSX } from '@ionic/core/components';
import React from 'react';
import { NavContext } from '../contexts/NavContext';

View File

@ -2,7 +2,8 @@ import {
ToastButton as ToastButtonCore,
ToastOptions as ToastOptionsCore,
toastController as toastControllerCore,
} from '@ionic/core';
} from '@ionic/core/components';
import { IonToast as IonToastCmp } from '@ionic/core/components/ion-toast.js';
import { createControllerComponent } from './createControllerComponent';
@ -27,6 +28,7 @@ const toastController = {
};
export const IonToast = /*@__PURE__*/ createControllerComponent<ToastOptions, HTMLIonToastElement>(
'IonToast',
toastController
'ion-toast',
toastController,
IonToastCmp
);

View File

@ -1,27 +0,0 @@
import React from 'react';
import { render, fireEvent, cleanup } from '@testing-library/react';
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 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 button = getByText('my button');
fireEvent.click(button);
expect(clickSpy).toHaveBeenCalled();
});
});

View File

@ -1,87 +0,0 @@
import React from 'react';
import { IonTabs, IonTabButton, IonLabel, IonIcon, IonTabBar } from '../index';
import { render, cleanup } from '@testing-library/react';
import { IonRouterOutlet } from '../IonRouterOutlet';
afterEach(cleanup);
describe('IonTabs', () => {
test('should render happy path', () => {
const { container } = render(
<IonTabs>
<IonRouterOutlet></IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="schedule">
<IonLabel>Schedule</IonLabel>
<IonIcon name="schedule"></IonIcon>
</IonTabButton>
<IonTabButton tab="speakers">
<IonLabel>Speakers</IonLabel>
<IonIcon name="speakers"></IonIcon>
</IonTabButton>
<IonTabButton tab="map">
<IonLabel>Map</IonLabel>
<IonIcon name="map"></IonIcon>
</IonTabButton>
<IonTabButton tab="about">
<IonLabel>About</IonLabel>
<IonIcon name="about"></IonIcon>
</IonTabButton>
</IonTabBar>
</IonTabs>
);
expect(container.children[0].children.length).toEqual(2);
expect(container.children[0].children[0].tagName).toEqual('DIV');
expect(container.children[0].children[0].className).toEqual('tabs-inner');
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',
]);
});
test('should allow for conditional children', () => {
const { container } = render(
<IonTabs>
<IonRouterOutlet></IonRouterOutlet>
<IonTabBar slot="bottom">
{false && (
<IonTabButton tab="schedule">
<IonLabel>Schedule</IonLabel>
<IonIcon name="schedule"></IonIcon>
</IonTabButton>
)}
<IonTabButton tab="speakers">
<IonLabel>Speakers</IonLabel>
<IonIcon name="speakers"></IonIcon>
</IonTabButton>
<IonTabButton tab="map">
<IonLabel>Map</IonLabel>
<IonIcon name="map"></IonIcon>
</IonTabButton>
<IonTabButton tab="about">
<IonLabel>About</IonLabel>
<IonIcon name="about"></IonIcon>
</IonTabButton>
</IonTabBar>
</IonTabs>
);
expect(container.children[0].children.length).toEqual(2);
expect(container.children[0].children[0].tagName).toEqual('DIV');
expect(container.children[0].children[0].className).toEqual('tabs-inner');
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',
]);
});
});

View File

@ -1,128 +0,0 @@
import React from 'react';
import { JSX } from '@ionic/core';
import { createReactComponent } from '../react-component-lib';
import { render, fireEvent, cleanup, RenderResult } from '@testing-library/react';
import { IonButton } from '../index';
afterEach(cleanup);
describe('createComponent - events', () => {
test('should set events on handler', () => {
const FakeOnClick = jest.fn((e) => e);
const IonButton = createReactComponent<JSX.IonButton, HTMLIonButtonElement>('ion-button');
const { getByText } = render(<IonButton onClick={FakeOnClick}>ButtonNameA</IonButton>);
fireEvent.click(getByText('ButtonNameA'));
expect(FakeOnClick).toBeCalledTimes(1);
});
test('should add custom events', () => {
const FakeIonFocus = jest.fn((e) => e);
const IonInput = createReactComponent<JSX.IonInput, HTMLIonInputElement>('ion-input');
const { getByText } = render(<IonInput onIonFocus={FakeIonFocus}>ButtonNameA</IonInput>);
const ionInputItem = getByText('ButtonNameA');
expect(Object.keys((ionInputItem as any).__events)).toEqual(['ionFocus']);
});
});
describe('createComponent - ref', () => {
test('should pass ref on to web component instance (RefObject)', () => {
const ionButtonRef: React.RefObject<any> = React.createRef();
const IonButton = createReactComponent<JSX.IonButton, HTMLIonButtonElement>('ion-button');
const { getByText } = render(<IonButton ref={ionButtonRef}>ButtonNameA</IonButton>);
const ionButtonItem = getByText('ButtonNameA');
expect(ionButtonRef.current).toEqual(ionButtonItem);
});
test('should pass ref on to web component instance (RefCallback)', () => {
let current
const ionButtonRef: React.RefCallback<any> = value => current = value;
const IonButton = createReactComponent<JSX.IonButton, HTMLIonButtonElement>('ion-button');
const { getByText } = render(<IonButton ref={ionButtonRef}>ButtonNameA</IonButton>);
const ionButtonItem = getByText('ButtonNameA');
expect(current).toEqual(ionButtonItem);
});
});
describe('createComponent - strict mode', () => {
beforeEach(() => (console.error = (...data: any[]) => {
throw new Error(...data);
}));
test('should work without errors in strict mode', () => {
const renderResult = render(
<React.StrictMode>
<IonButton>Strict Mode Rocks</IonButton>
</React.StrictMode>
);
expect(renderResult.getByText(/Rocks/)).toBeTruthy();
});
});
describe('when working with css classes', () => {
const myClass = 'my-class';
const myClass2 = 'my-class2';
const customClass = 'custom-class';
describe('when a class is added to className', () => {
let renderResult: RenderResult;
let button: HTMLElement;
beforeEach(() => {
renderResult = render(<IonButton className={myClass}>Hello!</IonButton>);
button = renderResult.getByText(/Hello/);
});
it('then it should be in the class list', () => {
expect(button.classList.contains(myClass)).toBeTruthy();
});
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>);
expect(button.classList.contains(customClass)).toBeTruthy();
});
});
describe('when multiple classes are added to className', () => {
let renderResult: RenderResult;
let button: HTMLElement;
beforeEach(() => {
renderResult = render(<IonButton className={myClass + ' ' + myClass2}>Hello!</IonButton>);
button = renderResult.getByText(/Hello/);
});
it('then both classes should be in class list', () => {
expect(button.classList.contains(myClass)).toBeTruthy();
expect(button.classList.contains(myClass2)).toBeTruthy();
});
it('when one of the classes is removed, then only the remaining class should be in class list', () => {
expect(button.classList.contains(myClass)).toBeTruthy();
expect(button.classList.contains(myClass2)).toBeTruthy();
renderResult.rerender(<IonButton className={myClass}>Hello!</IonButton>);
expect(button.classList.contains(myClass)).toBeTruthy();
expect(button.classList.contains(myClass2)).toBeFalsy();
});
it('when a custom class is added outside of React and one of the classes is removed, then only the remaining class and the custom class should be in class list', () => {
button.classList.add(customClass);
expect(button.classList.contains(myClass)).toBeTruthy();
expect(button.classList.contains(myClass2)).toBeTruthy();
expect(button.classList.contains(customClass)).toBeTruthy();
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();
});
});
});

View File

@ -1,7 +1,7 @@
import { OverlayEventDetail } from '@ionic/core';
import { OverlayEventDetail } from '@ionic/core/components';
import React from 'react';
import { attachProps, setRef } from './react-component-lib/utils';
import { attachProps, dashToPascalCase, defineCustomElement, setRef } from './react-component-lib/utils';
interface OverlayBase extends HTMLElement {
present: () => Promise<void>;
@ -20,9 +20,13 @@ export const createControllerComponent = <
OptionsType extends object,
OverlayType extends OverlayBase
>(
displayName: string,
controller: { create: (options: OptionsType) => Promise<OverlayType> }
tagName: string,
controller: { create: (options: OptionsType) => Promise<OverlayType> },
customElement?: any
) => {
defineCustomElement(tagName, customElement);
const displayName = dashToPascalCase(tagName);
const didDismissEventName = `on${displayName}DidDismiss`;
const didPresentEventName = `on${displayName}DidPresent`;
const willDismissEventName = `on${displayName}WillDismiss`;

View File

@ -1,16 +1,15 @@
import { OverlayEventDetail } from '@ionic/core'
import { OverlayEventDetail } from '@ionic/core/components'
import React from 'react';
import {
attachProps,
camelToDashCase,
dashToPascalCase,
defineCustomElement,
isCoveredByReact,
mergeRefs,
} from './react-component-lib/utils';
import {
createForwardRef
} from './utils';
import { createForwardRef } from './utils';
type InlineOverlayState = {
isOpen: boolean;
@ -26,8 +25,11 @@ interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<Elem
}
export const createInlineOverlayComponent = <PropType, ElementType>(
tagName: string
tagName: string,
customElement?: any
) => {
defineCustomElement(tagName, customElement);
const displayName = dashToPascalCase(tagName);
const ReactComponent = class extends React.Component<IonicReactInternalProps<PropType>, InlineOverlayState> {
ref: React.RefObject<HTMLElement>;

View File

@ -1,8 +1,8 @@
import { OverlayEventDetail } from '@ionic/core';
import { OverlayEventDetail } from '@ionic/core/components';
import React from 'react';
import ReactDOM from 'react-dom';
import { attachProps, setRef } from './react-component-lib/utils';
import { attachProps, dashToPascalCase, defineCustomElement, setRef } from './react-component-lib/utils';
interface OverlayElement extends HTMLElement {
present: () => Promise<void>;
@ -22,9 +22,13 @@ export const createOverlayComponent = <
OverlayComponent extends object,
OverlayType extends OverlayElement
>(
displayName: string,
controller: { create: (options: any) => Promise<OverlayType> }
tagName: string,
controller: { create: (options: any) => Promise<OverlayType> },
customElement?: any
) => {
defineCustomElement(tagName, customElement);
const displayName = dashToPascalCase(tagName);
const didDismissEventName = `on${displayName}DidDismiss`;
const didPresentEventName = `on${displayName}DidPresent`;
const willDismissEventName = `on${displayName}WillDismiss`;

View File

@ -1,4 +1,4 @@
import { AnimationBuilder } from '@ionic/core';
import { AnimationBuilder } from '@ionic/core/components';
import React from 'react';
import { NavContext } from '../contexts/NavContext';
@ -9,12 +9,11 @@ import {
attachProps,
camelToDashCase,
dashToPascalCase,
defineCustomElement,
isCoveredByReact,
mergeRefs,
} from './react-component-lib/utils';
import {
createForwardRef
} from './utils';
import { createForwardRef } from './utils';
interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<ElementType> {
forwardedRef?: React.ForwardedRef<ElementType>;
@ -27,8 +26,11 @@ interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<Elem
}
export const createRoutingComponent = <PropType, ElementType>(
tagName: string
tagName: string,
customElement?: any
) => {
defineCustomElement(tagName, customElement);
const displayName = dashToPascalCase(tagName);
const ReactComponent = class extends React.Component<IonicReactInternalProps<PropType>> {
context!: React.ContextType<typeof NavContext>;

View File

@ -1,4 +1,4 @@
import { AnimationBuilder } from '@ionic/core';
import { AnimationBuilder } from '@ionic/core/components';
import { RouterOptions } from '../models';
import { RouterDirection } from '../models/RouterDirection';

View File

@ -1,4 +1,4 @@
import { defineCustomElements } from '@ionic/core/loader';
import { initialize } from '@ionic/core/components';
import { addIcons } from 'ionicons';
import {
arrowBackSharp,
@ -34,6 +34,7 @@ export {
mdTransitionAnimation,
NavComponentWithProps,
setupConfig,
initialize,
IonicSwiper,
SpinnerTypes,
@ -60,7 +61,7 @@ export {
ToastOptions,
ToastButton
} from '@ionic/core';
} from '@ionic/core/components';
export * from './proxies';
export * from './routing-proxies';
@ -122,8 +123,13 @@ addIcons({
'search-sharp': searchSharp,
});
// TODO: defineCustomElements() is asyncronous
// We need to use the promise
if (typeof window !== 'undefined') {
defineCustomElements(window);
}
/**
* By default Ionic Framework hides elements that
* are not hydrated, but in the CE build there is no
* hydration.
* TODO: Remove when all integrations have been
* migrated to CE build.
*/
document.documentElement.classList.add('ion-ce');
initialize();

View File

@ -1,30 +1,35 @@
import { JSX } from '@ionic/core';
import { JSX } from '@ionic/core/components';
import { IonBackButton as IonBackButtonCmp } from '@ionic/core/components/ion-back-button.js';
import { IonRouterOutlet as IonRouterOutletCmp } from '@ionic/core/components/ion-router-outlet.js';
import { IonTabBar as IonTabBarCmp } from '@ionic/core/components/ion-tab-bar.js';
import { IonTabButton as IonTabButtonCmp } from '@ionic/core/components/ion-tab-button.js';
import { JSX as IoniconsJSX } from 'ionicons';
import { IonIcon as IonIconCmp } from 'ionicons/components/ion-icon.js';
import { /*@__PURE__*/ createReactComponent } from './react-component-lib';
export const IonTabButtonInner = /*@__PURE__*/ createReactComponent<
JSX.IonTabButton & { onIonTabButtonClick?: (e: CustomEvent) => void },
HTMLIonTabButtonElement
>('ion-tab-button');
>('ion-tab-button', IonTabButtonCmp);
export const IonTabBarInner = /*@__PURE__*/ createReactComponent<
JSX.IonTabBar,
HTMLIonTabBarElement
>('ion-tab-bar');
>('ion-tab-bar', IonTabBarCmp);
export const IonBackButtonInner = /*@__PURE__*/ createReactComponent<
Omit<JSX.IonBackButton, 'icon'>,
HTMLIonBackButtonElement
>('ion-back-button');
>('ion-back-button', IonBackButtonCmp);
export const IonRouterOutletInner = /*@__PURE__*/ createReactComponent<
JSX.IonRouterOutlet & {
setRef?: (val: HTMLIonRouterOutletElement) => void;
forwardedRef?: React.ForwardedRef<HTMLIonRouterOutletElement>;
},
HTMLIonRouterOutletElement
>('ion-router-outlet');
>('ion-router-outlet', IonRouterOutletCmp);
// ionicons
export const IonIconInner = /*@__PURE__*/ createReactComponent<
IoniconsJSX.IonIcon,
HTMLIonIconElement
>('ion-icon');
>('ion-icon', IonIconCmp);

View File

@ -1,4 +1,4 @@
import { JSX as LocalJSX } from '@ionic/core';
import { JSX as LocalJSX } from '@ionic/core/components';
import React from 'react';
import { NavContext } from '../../contexts/NavContext';

View File

@ -1,4 +1,4 @@
import { JSX as LocalJSX } from '@ionic/core';
import { JSX as LocalJSX } from '@ionic/core/components';
import React, { useContext } from 'react';
import { NavContext } from '../../contexts/NavContext';

View File

@ -1,4 +1,4 @@
import { JSX as LocalJSX } from '@ionic/core';
import { JSX as LocalJSX } from '@ionic/core/components';
import React from 'react';
import { RouterOptions } from '../../models';

View File

@ -1,4 +1,4 @@
import { JSX as LocalJSX } from '@ionic/core';
import { JSX as LocalJSX } from '@ionic/core/components';
import React, { Fragment } from 'react';
import { NavContext } from '../../contexts/NavContext';

View File

@ -3,75 +3,142 @@
/* auto-generated react proxies */
import { createReactComponent } from './react-component-lib';
import type { JSX } from '@ionic/core';
import type { JSX } from '@ionic/core/components';
import { IonAccordion as IonAccordionCmp } from '@ionic/core/components/ion-accordion.js';
import { IonAccordionGroup as IonAccordionGroupCmp } from '@ionic/core/components/ion-accordion-group.js';
import { IonApp as IonAppCmp } from '@ionic/core/components/ion-app.js';
import { IonAvatar as IonAvatarCmp } from '@ionic/core/components/ion-avatar.js';
import { IonBackdrop as IonBackdropCmp } from '@ionic/core/components/ion-backdrop.js';
import { IonBadge as IonBadgeCmp } from '@ionic/core/components/ion-badge.js';
import { IonBreadcrumb as IonBreadcrumbCmp } from '@ionic/core/components/ion-breadcrumb.js';
import { IonBreadcrumbs as IonBreadcrumbsCmp } from '@ionic/core/components/ion-breadcrumbs.js';
import { IonButtons as IonButtonsCmp } from '@ionic/core/components/ion-buttons.js';
import { IonCardContent as IonCardContentCmp } from '@ionic/core/components/ion-card-content.js';
import { IonCardHeader as IonCardHeaderCmp } from '@ionic/core/components/ion-card-header.js';
import { IonCardSubtitle as IonCardSubtitleCmp } from '@ionic/core/components/ion-card-subtitle.js';
import { IonCardTitle as IonCardTitleCmp } from '@ionic/core/components/ion-card-title.js';
import { IonCheckbox as IonCheckboxCmp } from '@ionic/core/components/ion-checkbox.js';
import { IonChip as IonChipCmp } from '@ionic/core/components/ion-chip.js';
import { IonCol as IonColCmp } from '@ionic/core/components/ion-col.js';
import { IonContent as IonContentCmp } from '@ionic/core/components/ion-content.js';
import { IonDatetime as IonDatetimeCmp } from '@ionic/core/components/ion-datetime.js';
import { IonFab as IonFabCmp } from '@ionic/core/components/ion-fab.js';
import { IonFabList as IonFabListCmp } from '@ionic/core/components/ion-fab-list.js';
import { IonFooter as IonFooterCmp } from '@ionic/core/components/ion-footer.js';
import { IonGrid as IonGridCmp } from '@ionic/core/components/ion-grid.js';
import { IonHeader as IonHeaderCmp } from '@ionic/core/components/ion-header.js';
import { IonImg as IonImgCmp } from '@ionic/core/components/ion-img.js';
import { IonInfiniteScroll as IonInfiniteScrollCmp } from '@ionic/core/components/ion-infinite-scroll.js';
import { IonInfiniteScrollContent as IonInfiniteScrollContentCmp } from '@ionic/core/components/ion-infinite-scroll-content.js';
import { IonInput as IonInputCmp } from '@ionic/core/components/ion-input.js';
import { IonItemDivider as IonItemDividerCmp } from '@ionic/core/components/ion-item-divider.js';
import { IonItemGroup as IonItemGroupCmp } from '@ionic/core/components/ion-item-group.js';
import { IonItemOptions as IonItemOptionsCmp } from '@ionic/core/components/ion-item-options.js';
import { IonItemSliding as IonItemSlidingCmp } from '@ionic/core/components/ion-item-sliding.js';
import { IonLabel as IonLabelCmp } from '@ionic/core/components/ion-label.js';
import { IonList as IonListCmp } from '@ionic/core/components/ion-list.js';
import { IonListHeader as IonListHeaderCmp } from '@ionic/core/components/ion-list-header.js';
import { IonMenu as IonMenuCmp } from '@ionic/core/components/ion-menu.js';
import { IonMenuButton as IonMenuButtonCmp } from '@ionic/core/components/ion-menu-button.js';
import { IonMenuToggle as IonMenuToggleCmp } from '@ionic/core/components/ion-menu-toggle.js';
import { IonNav as IonNavCmp } from '@ionic/core/components/ion-nav.js';
import { IonNavLink as IonNavLinkCmp } from '@ionic/core/components/ion-nav-link.js';
import { IonNote as IonNoteCmp } from '@ionic/core/components/ion-note.js';
import { IonProgressBar as IonProgressBarCmp } from '@ionic/core/components/ion-progress-bar.js';
import { IonRadio as IonRadioCmp } from '@ionic/core/components/ion-radio.js';
import { IonRadioGroup as IonRadioGroupCmp } from '@ionic/core/components/ion-radio-group.js';
import { IonRange as IonRangeCmp } from '@ionic/core/components/ion-range.js';
import { IonRefresher as IonRefresherCmp } from '@ionic/core/components/ion-refresher.js';
import { IonRefresherContent as IonRefresherContentCmp } from '@ionic/core/components/ion-refresher-content.js';
import { IonReorder as IonReorderCmp } from '@ionic/core/components/ion-reorder.js';
import { IonReorderGroup as IonReorderGroupCmp } from '@ionic/core/components/ion-reorder-group.js';
import { IonRippleEffect as IonRippleEffectCmp } from '@ionic/core/components/ion-ripple-effect.js';
import { IonRow as IonRowCmp } from '@ionic/core/components/ion-row.js';
import { IonSearchbar as IonSearchbarCmp } from '@ionic/core/components/ion-searchbar.js';
import { IonSegment as IonSegmentCmp } from '@ionic/core/components/ion-segment.js';
import { IonSegmentButton as IonSegmentButtonCmp } from '@ionic/core/components/ion-segment-button.js';
import { IonSelect as IonSelectCmp } from '@ionic/core/components/ion-select.js';
import { IonSelectOption as IonSelectOptionCmp } from '@ionic/core/components/ion-select-option.js';
import { IonSkeletonText as IonSkeletonTextCmp } from '@ionic/core/components/ion-skeleton-text.js';
import { IonSlide as IonSlideCmp } from '@ionic/core/components/ion-slide.js';
import { IonSlides as IonSlidesCmp } from '@ionic/core/components/ion-slides.js';
import { IonSpinner as IonSpinnerCmp } from '@ionic/core/components/ion-spinner.js';
import { IonSplitPane as IonSplitPaneCmp } from '@ionic/core/components/ion-split-pane.js';
import { IonTab as IonTabCmp } from '@ionic/core/components/ion-tab.js';
import { IonText as IonTextCmp } from '@ionic/core/components/ion-text.js';
import { IonTextarea as IonTextareaCmp } from '@ionic/core/components/ion-textarea.js';
import { IonThumbnail as IonThumbnailCmp } from '@ionic/core/components/ion-thumbnail.js';
import { IonTitle as IonTitleCmp } from '@ionic/core/components/ion-title.js';
import { IonToggle as IonToggleCmp } from '@ionic/core/components/ion-toggle.js';
import { IonToolbar as IonToolbarCmp } from '@ionic/core/components/ion-toolbar.js';
import { IonVirtualScroll as IonVirtualScrollCmp } from '@ionic/core/components/ion-virtual-scroll.js';
export const IonAccordion = /*@__PURE__*/createReactComponent<JSX.IonAccordion, HTMLIonAccordionElement>('ion-accordion');
export const IonAccordionGroup = /*@__PURE__*/createReactComponent<JSX.IonAccordionGroup, HTMLIonAccordionGroupElement>('ion-accordion-group');
export const IonApp = /*@__PURE__*/createReactComponent<JSX.IonApp, HTMLIonAppElement>('ion-app');
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 IonBreadcrumb = /*@__PURE__*/createReactComponent<JSX.IonBreadcrumb, HTMLIonBreadcrumbElement>('ion-breadcrumb');
export const IonBreadcrumbs = /*@__PURE__*/createReactComponent<JSX.IonBreadcrumbs, HTMLIonBreadcrumbsElement>('ion-breadcrumbs');
export const IonButtons = /*@__PURE__*/createReactComponent<JSX.IonButtons, HTMLIonButtonsElement>('ion-buttons');
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 IonChip = /*@__PURE__*/createReactComponent<JSX.IonChip, HTMLIonChipElement>('ion-chip');
export const IonCol = /*@__PURE__*/createReactComponent<JSX.IonCol, HTMLIonColElement>('ion-col');
export const IonContent = /*@__PURE__*/createReactComponent<JSX.IonContent, HTMLIonContentElement>('ion-content');
export const IonDatetime = /*@__PURE__*/createReactComponent<JSX.IonDatetime, HTMLIonDatetimeElement>('ion-datetime');
export const IonFab = /*@__PURE__*/createReactComponent<JSX.IonFab, HTMLIonFabElement>('ion-fab');
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 IonItemDivider = /*@__PURE__*/createReactComponent<JSX.IonItemDivider, HTMLIonItemDividerElement>('ion-item-divider');
export const IonItemGroup = /*@__PURE__*/createReactComponent<JSX.IonItemGroup, HTMLIonItemGroupElement>('ion-item-group');
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 IonNav = /*@__PURE__*/createReactComponent<JSX.IonNav, HTMLIonNavElement>('ion-nav');
export const IonNavLink = /*@__PURE__*/createReactComponent<JSX.IonNavLink, HTMLIonNavLinkElement>('ion-nav-link');
export const IonNote = /*@__PURE__*/createReactComponent<JSX.IonNote, HTMLIonNoteElement>('ion-note');
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 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 IonTab = /*@__PURE__*/createReactComponent<JSX.IonTab, HTMLIonTabElement>('ion-tab');
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 IonAccordion = /*@__PURE__*/createReactComponent<JSX.IonAccordion, HTMLIonAccordionElement>('ion-accordion', IonAccordionCmp);
export const IonAccordionGroup = /*@__PURE__*/createReactComponent<JSX.IonAccordionGroup, HTMLIonAccordionGroupElement>('ion-accordion-group', IonAccordionGroupCmp);
export const IonApp = /*@__PURE__*/createReactComponent<JSX.IonApp, HTMLIonAppElement>('ion-app', IonAppCmp);
export const IonAvatar = /*@__PURE__*/createReactComponent<JSX.IonAvatar, HTMLIonAvatarElement>('ion-avatar', IonAvatarCmp);
export const IonBackdrop = /*@__PURE__*/createReactComponent<JSX.IonBackdrop, HTMLIonBackdropElement>('ion-backdrop', IonBackdropCmp);
export const IonBadge = /*@__PURE__*/createReactComponent<JSX.IonBadge, HTMLIonBadgeElement>('ion-badge', IonBadgeCmp);
export const IonBreadcrumb = /*@__PURE__*/createReactComponent<JSX.IonBreadcrumb, HTMLIonBreadcrumbElement>('ion-breadcrumb', IonBreadcrumbCmp);
export const IonBreadcrumbs = /*@__PURE__*/createReactComponent<JSX.IonBreadcrumbs, HTMLIonBreadcrumbsElement>('ion-breadcrumbs', IonBreadcrumbsCmp);
export const IonButtons = /*@__PURE__*/createReactComponent<JSX.IonButtons, HTMLIonButtonsElement>('ion-buttons', IonButtonsCmp);
export const IonCardContent = /*@__PURE__*/createReactComponent<JSX.IonCardContent, HTMLIonCardContentElement>('ion-card-content', IonCardContentCmp);
export const IonCardHeader = /*@__PURE__*/createReactComponent<JSX.IonCardHeader, HTMLIonCardHeaderElement>('ion-card-header', IonCardHeaderCmp);
export const IonCardSubtitle = /*@__PURE__*/createReactComponent<JSX.IonCardSubtitle, HTMLIonCardSubtitleElement>('ion-card-subtitle', IonCardSubtitleCmp);
export const IonCardTitle = /*@__PURE__*/createReactComponent<JSX.IonCardTitle, HTMLIonCardTitleElement>('ion-card-title', IonCardTitleCmp);
export const IonCheckbox = /*@__PURE__*/createReactComponent<JSX.IonCheckbox, HTMLIonCheckboxElement>('ion-checkbox', IonCheckboxCmp);
export const IonChip = /*@__PURE__*/createReactComponent<JSX.IonChip, HTMLIonChipElement>('ion-chip', IonChipCmp);
export const IonCol = /*@__PURE__*/createReactComponent<JSX.IonCol, HTMLIonColElement>('ion-col', IonColCmp);
export const IonContent = /*@__PURE__*/createReactComponent<JSX.IonContent, HTMLIonContentElement>('ion-content', IonContentCmp);
export const IonDatetime = /*@__PURE__*/createReactComponent<JSX.IonDatetime, HTMLIonDatetimeElement>('ion-datetime', IonDatetimeCmp);
export const IonFab = /*@__PURE__*/createReactComponent<JSX.IonFab, HTMLIonFabElement>('ion-fab', IonFabCmp);
export const IonFabList = /*@__PURE__*/createReactComponent<JSX.IonFabList, HTMLIonFabListElement>('ion-fab-list', IonFabListCmp);
export const IonFooter = /*@__PURE__*/createReactComponent<JSX.IonFooter, HTMLIonFooterElement>('ion-footer', IonFooterCmp);
export const IonGrid = /*@__PURE__*/createReactComponent<JSX.IonGrid, HTMLIonGridElement>('ion-grid', IonGridCmp);
export const IonHeader = /*@__PURE__*/createReactComponent<JSX.IonHeader, HTMLIonHeaderElement>('ion-header', IonHeaderCmp);
export const IonImg = /*@__PURE__*/createReactComponent<JSX.IonImg, HTMLIonImgElement>('ion-img', IonImgCmp);
export const IonInfiniteScroll = /*@__PURE__*/createReactComponent<JSX.IonInfiniteScroll, HTMLIonInfiniteScrollElement>('ion-infinite-scroll', IonInfiniteScrollCmp);
export const IonInfiniteScrollContent = /*@__PURE__*/createReactComponent<JSX.IonInfiniteScrollContent, HTMLIonInfiniteScrollContentElement>('ion-infinite-scroll-content', IonInfiniteScrollContentCmp);
export const IonInput = /*@__PURE__*/createReactComponent<JSX.IonInput, HTMLIonInputElement>('ion-input', IonInputCmp);
export const IonItemDivider = /*@__PURE__*/createReactComponent<JSX.IonItemDivider, HTMLIonItemDividerElement>('ion-item-divider', IonItemDividerCmp);
export const IonItemGroup = /*@__PURE__*/createReactComponent<JSX.IonItemGroup, HTMLIonItemGroupElement>('ion-item-group', IonItemGroupCmp);
export const IonItemOptions = /*@__PURE__*/createReactComponent<JSX.IonItemOptions, HTMLIonItemOptionsElement>('ion-item-options', IonItemOptionsCmp);
export const IonItemSliding = /*@__PURE__*/createReactComponent<JSX.IonItemSliding, HTMLIonItemSlidingElement>('ion-item-sliding', IonItemSlidingCmp);
export const IonLabel = /*@__PURE__*/createReactComponent<JSX.IonLabel, HTMLIonLabelElement>('ion-label', IonLabelCmp);
export const IonList = /*@__PURE__*/createReactComponent<JSX.IonList, HTMLIonListElement>('ion-list', IonListCmp);
export const IonListHeader = /*@__PURE__*/createReactComponent<JSX.IonListHeader, HTMLIonListHeaderElement>('ion-list-header', IonListHeaderCmp);
export const IonMenu = /*@__PURE__*/createReactComponent<JSX.IonMenu, HTMLIonMenuElement>('ion-menu', IonMenuCmp);
export const IonMenuButton = /*@__PURE__*/createReactComponent<JSX.IonMenuButton, HTMLIonMenuButtonElement>('ion-menu-button', IonMenuButtonCmp);
export const IonMenuToggle = /*@__PURE__*/createReactComponent<JSX.IonMenuToggle, HTMLIonMenuToggleElement>('ion-menu-toggle', IonMenuToggleCmp);
export const IonNav = /*@__PURE__*/createReactComponent<JSX.IonNav, HTMLIonNavElement>('ion-nav', IonNavCmp);
export const IonNavLink = /*@__PURE__*/createReactComponent<JSX.IonNavLink, HTMLIonNavLinkElement>('ion-nav-link', IonNavLinkCmp);
export const IonNote = /*@__PURE__*/createReactComponent<JSX.IonNote, HTMLIonNoteElement>('ion-note', IonNoteCmp);
export const IonProgressBar = /*@__PURE__*/createReactComponent<JSX.IonProgressBar, HTMLIonProgressBarElement>('ion-progress-bar', IonProgressBarCmp);
export const IonRadio = /*@__PURE__*/createReactComponent<JSX.IonRadio, HTMLIonRadioElement>('ion-radio', IonRadioCmp);
export const IonRadioGroup = /*@__PURE__*/createReactComponent<JSX.IonRadioGroup, HTMLIonRadioGroupElement>('ion-radio-group', IonRadioGroupCmp);
export const IonRange = /*@__PURE__*/createReactComponent<JSX.IonRange, HTMLIonRangeElement>('ion-range', IonRangeCmp);
export const IonRefresher = /*@__PURE__*/createReactComponent<JSX.IonRefresher, HTMLIonRefresherElement>('ion-refresher', IonRefresherCmp);
export const IonRefresherContent = /*@__PURE__*/createReactComponent<JSX.IonRefresherContent, HTMLIonRefresherContentElement>('ion-refresher-content', IonRefresherContentCmp);
export const IonReorder = /*@__PURE__*/createReactComponent<JSX.IonReorder, HTMLIonReorderElement>('ion-reorder', IonReorderCmp);
export const IonReorderGroup = /*@__PURE__*/createReactComponent<JSX.IonReorderGroup, HTMLIonReorderGroupElement>('ion-reorder-group', IonReorderGroupCmp);
export const IonRippleEffect = /*@__PURE__*/createReactComponent<JSX.IonRippleEffect, HTMLIonRippleEffectElement>('ion-ripple-effect', IonRippleEffectCmp);
export const IonRow = /*@__PURE__*/createReactComponent<JSX.IonRow, HTMLIonRowElement>('ion-row', IonRowCmp);
export const IonSearchbar = /*@__PURE__*/createReactComponent<JSX.IonSearchbar, HTMLIonSearchbarElement>('ion-searchbar', IonSearchbarCmp);
export const IonSegment = /*@__PURE__*/createReactComponent<JSX.IonSegment, HTMLIonSegmentElement>('ion-segment', IonSegmentCmp);
export const IonSegmentButton = /*@__PURE__*/createReactComponent<JSX.IonSegmentButton, HTMLIonSegmentButtonElement>('ion-segment-button', IonSegmentButtonCmp);
export const IonSelect = /*@__PURE__*/createReactComponent<JSX.IonSelect, HTMLIonSelectElement>('ion-select', IonSelectCmp);
export const IonSelectOption = /*@__PURE__*/createReactComponent<JSX.IonSelectOption, HTMLIonSelectOptionElement>('ion-select-option', IonSelectOptionCmp);
export const IonSkeletonText = /*@__PURE__*/createReactComponent<JSX.IonSkeletonText, HTMLIonSkeletonTextElement>('ion-skeleton-text', IonSkeletonTextCmp);
export const IonSlide = /*@__PURE__*/createReactComponent<JSX.IonSlide, HTMLIonSlideElement>('ion-slide', IonSlideCmp);
export const IonSlides = /*@__PURE__*/createReactComponent<JSX.IonSlides, HTMLIonSlidesElement>('ion-slides', IonSlidesCmp);
export const IonSpinner = /*@__PURE__*/createReactComponent<JSX.IonSpinner, HTMLIonSpinnerElement>('ion-spinner', IonSpinnerCmp);
export const IonSplitPane = /*@__PURE__*/createReactComponent<JSX.IonSplitPane, HTMLIonSplitPaneElement>('ion-split-pane', IonSplitPaneCmp);
export const IonTab = /*@__PURE__*/createReactComponent<JSX.IonTab, HTMLIonTabElement>('ion-tab', IonTabCmp);
export const IonText = /*@__PURE__*/createReactComponent<JSX.IonText, HTMLIonTextElement>('ion-text', IonTextCmp);
export const IonTextarea = /*@__PURE__*/createReactComponent<JSX.IonTextarea, HTMLIonTextareaElement>('ion-textarea', IonTextareaCmp);
export const IonThumbnail = /*@__PURE__*/createReactComponent<JSX.IonThumbnail, HTMLIonThumbnailElement>('ion-thumbnail', IonThumbnailCmp);
export const IonTitle = /*@__PURE__*/createReactComponent<JSX.IonTitle, HTMLIonTitleElement>('ion-title', IonTitleCmp);
export const IonToggle = /*@__PURE__*/createReactComponent<JSX.IonToggle, HTMLIonToggleElement>('ion-toggle', IonToggleCmp);
export const IonToolbar = /*@__PURE__*/createReactComponent<JSX.IonToolbar, HTMLIonToolbarElement>('ion-toolbar', IonToolbarCmp);
export const IonVirtualScroll = /*@__PURE__*/createReactComponent<JSX.IonVirtualScroll, HTMLIonVirtualScrollElement>('ion-virtual-scroll', IonVirtualScrollCmp);

View File

@ -4,6 +4,7 @@ import {
attachProps,
createForwardRef,
dashToPascalCase,
defineCustomElement,
isCoveredByReact,
mergeRefs,
} from './utils';
@ -24,14 +25,16 @@ export const createReactComponent = <
ExpandedPropsTypes = {}
>(
tagName: string,
customElement?: any,
ReactComponentContext?: React.Context<ContextStateType>,
manipulatePropsFunction?: (
originalProps: StencilReactInternalProps<ElementType>,
propsToPass: any,
) => ExpandedPropsTypes,
) => {
const displayName = dashToPascalCase(tagName);
defineCustomElement(tagName, customElement);
const displayName = dashToPascalCase(tagName);
const ReactComponent = class extends React.Component<StencilReactInternalProps<ElementType>> {
componentEl!: ElementType;

View File

@ -2,7 +2,13 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { OverlayEventDetail } from './interfaces';
import { StencilReactForwardedRef, attachProps, setRef } from './utils';
import {
StencilReactForwardedRef,
attachProps,
dashToPascalCase,
defineCustomElement,
setRef,
} from './utils';
interface OverlayElement extends HTMLElement {
present: () => Promise<void>;
@ -22,9 +28,13 @@ export const createOverlayComponent = <
OverlayComponent extends object,
OverlayType extends OverlayElement
>(
displayName: string,
controller: { create: (options: any) => Promise<OverlayType> }
tagName: string,
controller: { create: (options: any) => Promise<OverlayType> },
customElement?: any
) => {
defineCustomElement(tagName, customElement);
const displayName = dashToPascalCase(tagName);
const didDismissEventName = `on${displayName}DidDismiss`;
const didPresentEventName = `on${displayName}DidPresent`;
const willDismissEventName = `on${displayName}WillDismiss`;

View File

@ -43,5 +43,15 @@ export const createForwardRef = <PropType, ElementType>(
return React.forwardRef(forwardRef);
};
export const defineCustomElement = (tagName: string, customElement: any) => {
if (
customElement !== undefined &&
typeof customElements !== 'undefined' &&
!customElements.get(tagName)
) {
customElements.define(tagName, customElement);
}
}
export * from './attachProps';
export * from './case';

View File

@ -1,4 +1,10 @@
import type { JSX } from '@ionic/core';
import type { JSX } from '@ionic/core/components';
import { IonButton as IonButtonCmp } from '@ionic/core/components/ion-button.js';
import { IonCard as IonCardCmp } from '@ionic/core/components/ion-card.js';
import { IonFabButton as IonFabButtonCmp } from '@ionic/core/components/ion-fab-button.js';
import { IonItemOption as IonItemOptionCmp } from '@ionic/core/components/ion-item-option.js';
import { IonItem as IonItemCmp } from '@ionic/core/components/ion-item.js';
import { IonRouterLink as IonRouterLinkCmp } from '@ionic/core/components/ion-router-link.js';
import { createRoutingComponent } from './createRoutingComponent';
import { HrefProps } from './hrefprops';
@ -6,29 +12,29 @@ import { HrefProps } from './hrefprops';
export const IonRouterLink = /*@__PURE__*/ createRoutingComponent<
HrefProps<JSX.IonRouterLink>,
HTMLIonRouterLinkElement
>('ion-router-link');
>('ion-router-link', IonRouterLinkCmp);
export const IonButton = /*@__PURE__*/ createRoutingComponent<
HrefProps<JSX.IonButton>,
HTMLIonButtonElement
>('ion-button');
>('ion-button', IonButtonCmp);
export const IonCard = /*@__PURE__*/ createRoutingComponent<
HrefProps<JSX.IonCard>,
HTMLIonCardElement
>('ion-card');
>('ion-card', IonCardCmp);
export const IonFabButton = /*@__PURE__*/ createRoutingComponent<
HrefProps<JSX.IonFabButton>,
HTMLIonFabButtonElement
>('ion-fab-button');
>('ion-fab-button', IonFabButtonCmp);
export const IonItem = /*@__PURE__*/ createRoutingComponent<
HrefProps<JSX.IonItem>,
HTMLIonItemElement
>('ion-item');
>('ion-item', IonItemCmp);
export const IonItemOption = /*@__PURE__*/ createRoutingComponent<
HrefProps<JSX.IonItemOption>,
HTMLIonItemOptionElement
>('ion-item-option');
>('ion-item-option', IonItemOptionCmp);

View File

@ -3,7 +3,7 @@ import {
Platforms,
getPlatforms as getPlatformsCore,
isPlatform as isPlatformCore,
} from '@ionic/core';
} from '@ionic/core/components';
import React from 'react';
import { IonicReactProps } from '../IonicReactProps';