mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
refactor(react): transition to Stencil React bindings (#23826)
This commit is contained in:
16
core/package-lock.json
generated
16
core/package-lock.json
generated
@ -18,6 +18,7 @@
|
||||
"@jest/core": "^26.6.3",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/react-output-target": "^0.0.12",
|
||||
"@stencil/sass": "1.3.2",
|
||||
"@stencil/vue-output-target": "^0.5.1",
|
||||
"@types/jest": "^26.0.20",
|
||||
@ -1367,6 +1368,15 @@
|
||||
"npm": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/react-output-target": {
|
||||
"version": "0.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.0.12.tgz",
|
||||
"integrity": "sha512-X/lWAI/FW4tg/pjwe5UWy8KbRk2vWcWR+S6tBqNzKO6pKD6qr60dfajN13EO9nnm5hGr48FP1m/M8kqFbjpZrg==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@stencil/core": ">=1.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/sass": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-1.3.2.tgz",
|
||||
@ -15010,6 +15020,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.6.0.tgz",
|
||||
"integrity": "sha512-QsxWayZyusnqSZrlCl81R71rA3KqFjVVQSH4E0rGN15F1GdQaFonKlHLyCOLKLig1zzC+DQkLLiUuocexuvdeQ=="
|
||||
},
|
||||
"@stencil/react-output-target": {
|
||||
"version": "0.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.0.12.tgz",
|
||||
"integrity": "sha512-X/lWAI/FW4tg/pjwe5UWy8KbRk2vWcWR+S6tBqNzKO6pKD6qr60dfajN13EO9nnm5hGr48FP1m/M8kqFbjpZrg==",
|
||||
"dev": true
|
||||
},
|
||||
"@stencil/sass": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/sass/-/sass-1.3.2.tgz",
|
||||
|
@ -40,6 +40,7 @@
|
||||
"@jest/core": "^26.6.3",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@rollup/plugin-virtual": "^2.0.3",
|
||||
"@stencil/react-output-target": "^0.0.12",
|
||||
"@stencil/sass": "1.3.2",
|
||||
"@stencil/vue-output-target": "^0.5.1",
|
||||
"@types/jest": "^26.0.20",
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Config } from '@stencil/core';
|
||||
import { sass } from '@stencil/sass';
|
||||
import { vueOutputTarget } from '@stencil/vue-output-target';
|
||||
import { reactOutputTarget } from '@stencil/react-output-target';
|
||||
|
||||
// @ts-ignore
|
||||
import { apiSpecGenerator } from './scripts/api-spec-generator';
|
||||
@ -61,6 +62,40 @@ export const config: Config = {
|
||||
})
|
||||
],
|
||||
outputTargets: [
|
||||
reactOutputTarget({
|
||||
componentCorePackage: '@ionic/core',
|
||||
includePolyfills: false,
|
||||
includeDefineCustomElements: false,
|
||||
proxiesFile: '../packages/react/src/components/proxies.ts',
|
||||
excludeComponents: [
|
||||
// Routing
|
||||
'ion-router',
|
||||
'ion-route',
|
||||
'ion-route-redirect',
|
||||
'ion-router-link',
|
||||
'ion-router-outlet',
|
||||
'ion-back-button',
|
||||
'ion-tab-button',
|
||||
'ion-tabs',
|
||||
'ion-tab-bar',
|
||||
'ion-button',
|
||||
'ion-card',
|
||||
'ion-fab-button',
|
||||
'ion-item',
|
||||
'ion-item-option',
|
||||
|
||||
// Overlays
|
||||
'ion-action-sheet',
|
||||
'ion-alert',
|
||||
'ion-loading',
|
||||
'ion-modal',
|
||||
'ion-picker',
|
||||
'ion-popover',
|
||||
'ion-toast',
|
||||
|
||||
'ion-icon'
|
||||
]
|
||||
}),
|
||||
vueOutputTarget({
|
||||
componentCorePackage: '@ionic/core',
|
||||
includeImportCustomElements: true,
|
||||
|
15
packages/react-router/test-app/package-lock.json
generated
15
packages/react-router/test-app/package-lock.json
generated
@ -77,7 +77,7 @@
|
||||
"style-loader": "0.23.1",
|
||||
"terser-webpack-plugin": "2.3.4",
|
||||
"ts-pnp": "1.1.5",
|
||||
"typescript": "3.7.4",
|
||||
"typescript": "^3.9.5",
|
||||
"url-loader": "2.3.0",
|
||||
"wait-on": "^5.3.0",
|
||||
"webpack": "4.41.5",
|
||||
@ -19603,9 +19603,10 @@
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "3.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz",
|
||||
"integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==",
|
||||
"version": "3.9.10",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@ -37499,9 +37500,9 @@
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz",
|
||||
"integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw=="
|
||||
"version": "3.9.10",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="
|
||||
},
|
||||
"undefsafe": {
|
||||
"version": "2.0.3",
|
||||
|
@ -72,7 +72,7 @@
|
||||
"style-loader": "0.23.1",
|
||||
"terser-webpack-plugin": "2.3.4",
|
||||
"ts-pnp": "1.1.5",
|
||||
"typescript": "3.7.4",
|
||||
"typescript": "^3.9.5",
|
||||
"url-loader": "2.3.0",
|
||||
"wait-on": "^5.3.0",
|
||||
"webpack": "4.41.5",
|
||||
|
@ -4,8 +4,8 @@ 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';
|
||||
import { deprecationWarning } from './utils/dev';
|
||||
|
||||
interface IonIconProps {
|
||||
ariaLabel?: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { JSX } from '@ionic/core';
|
||||
import { createReactComponent } from '../createComponent';
|
||||
import { createReactComponent } from '../react-component-lib';
|
||||
import { render, fireEvent, cleanup, RenderResult } from '@testing-library/react';
|
||||
import { IonButton } from '../index';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as utils from '../utils';
|
||||
import * as utils from '../react-component-lib/utils';
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
|
||||
describe('isCoveredByReact', () => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { OverlayEventDetail } from '@ionic/core';
|
||||
import React from 'react';
|
||||
|
||||
import { attachProps, setRef } from './utils';
|
||||
import { attachProps, setRef } from './react-component-lib/utils';
|
||||
|
||||
interface OverlayBase extends HTMLElement {
|
||||
present: () => Promise<void>;
|
||||
|
@ -4,10 +4,12 @@ import React from 'react';
|
||||
import {
|
||||
attachProps,
|
||||
camelToDashCase,
|
||||
createForwardRef,
|
||||
dashToPascalCase,
|
||||
isCoveredByReact,
|
||||
mergeRefs,
|
||||
} from './react-component-lib/utils';
|
||||
import {
|
||||
createForwardRef
|
||||
} from './utils';
|
||||
|
||||
type InlineOverlayState = {
|
||||
|
@ -2,7 +2,7 @@ import { OverlayEventDetail } from '@ionic/core';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { attachProps, setRef } from './utils';
|
||||
import { attachProps, setRef } from './react-component-lib/utils';
|
||||
|
||||
interface OverlayElement extends HTMLElement {
|
||||
present: () => Promise<void>;
|
||||
|
@ -8,10 +8,12 @@ import { RouterDirection } from '../models/RouterDirection';
|
||||
import {
|
||||
attachProps,
|
||||
camelToDashCase,
|
||||
createForwardRef,
|
||||
dashToPascalCase,
|
||||
isCoveredByReact,
|
||||
mergeRefs,
|
||||
} from './react-component-lib/utils';
|
||||
import {
|
||||
createForwardRef
|
||||
} from './utils';
|
||||
|
||||
interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<ElementType> {
|
||||
@ -24,9 +26,8 @@ interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<Elem
|
||||
routerAnimation?: AnimationBuilder;
|
||||
}
|
||||
|
||||
export const createReactComponent = <PropType, ElementType>(
|
||||
tagName: string,
|
||||
routerLinkComponent = false
|
||||
export const createRoutingComponent = <PropType, ElementType>(
|
||||
tagName: string
|
||||
) => {
|
||||
const displayName = dashToPascalCase(tagName);
|
||||
const ReactComponent = class extends React.Component<IonicReactInternalProps<PropType>> {
|
||||
@ -86,7 +87,6 @@ export const createReactComponent = <PropType, ElementType>(
|
||||
style,
|
||||
};
|
||||
|
||||
if (routerLinkComponent) {
|
||||
if (this.props.routerLink && !this.props.href) {
|
||||
newProps.href = this.props.routerLink;
|
||||
}
|
||||
@ -101,7 +101,6 @@ export const createReactComponent = <PropType, ElementType>(
|
||||
} else {
|
||||
newProps.onClick = this.handleClick;
|
||||
}
|
||||
}
|
||||
|
||||
return React.createElement(tagName, newProps, children);
|
||||
}
|
@ -63,6 +63,7 @@ export {
|
||||
ToastButton
|
||||
} from '@ionic/core';
|
||||
export * from './proxies';
|
||||
export * from './routing-proxies';
|
||||
|
||||
// createControllerComponent
|
||||
export { IonAlert } from './IonAlert';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { JSX } from '@ionic/core';
|
||||
import { JSX as IoniconsJSX } from 'ionicons';
|
||||
|
||||
import { /*@__PURE__*/ createReactComponent } from './createComponent';
|
||||
import { /*@__PURE__*/ createReactComponent } from './react-component-lib';
|
||||
|
||||
export const IonTabButtonInner = /*@__PURE__*/ createReactComponent<
|
||||
JSX.IonTabButton & { onIonTabButtonClick?: (e: CustomEvent) => void },
|
||||
|
@ -1,255 +1,77 @@
|
||||
import { JSX } from '@ionic/core';
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
/* auto-generated react proxies */
|
||||
import { createReactComponent } from './react-component-lib';
|
||||
|
||||
import { createReactComponent } from './createComponent';
|
||||
import { HrefProps } from './hrefprops';
|
||||
import type { JSX } from '@ionic/core';
|
||||
|
||||
// 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 IonAccordion = /*@__PURE__*/ createReactComponent<JSX.IonAccordion, HTMLIonAccordionElement>(
|
||||
'ion-accordion'
|
||||
);
|
||||
export const IonAccordionGroup = /*@__PURE__*/ createReactComponent<JSX.IonAccordionGroup, HTMLIonAccordionGroupElement>(
|
||||
'ion-accordion-group'
|
||||
);
|
||||
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 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 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');
|
||||
|
@ -0,0 +1,93 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
attachProps,
|
||||
createForwardRef,
|
||||
dashToPascalCase,
|
||||
isCoveredByReact,
|
||||
mergeRefs,
|
||||
} from './utils';
|
||||
|
||||
export interface HTMLStencilElement extends HTMLElement {
|
||||
componentOnReady(): Promise<this>;
|
||||
}
|
||||
|
||||
interface StencilReactInternalProps<ElementType> extends React.HTMLAttributes<ElementType> {
|
||||
forwardedRef: React.RefObject<ElementType>;
|
||||
ref?: React.Ref<any>;
|
||||
}
|
||||
|
||||
export const createReactComponent = <
|
||||
PropType,
|
||||
ElementType extends HTMLStencilElement,
|
||||
ContextStateType = {},
|
||||
ExpandedPropsTypes = {}
|
||||
>(
|
||||
tagName: string,
|
||||
ReactComponentContext?: React.Context<ContextStateType>,
|
||||
manipulatePropsFunction?: (
|
||||
originalProps: StencilReactInternalProps<ElementType>,
|
||||
propsToPass: any,
|
||||
) => ExpandedPropsTypes,
|
||||
) => {
|
||||
const displayName = dashToPascalCase(tagName);
|
||||
|
||||
const ReactComponent = class extends React.Component<StencilReactInternalProps<ElementType>> {
|
||||
componentEl!: ElementType;
|
||||
|
||||
setComponentElRef = (element: ElementType) => {
|
||||
this.componentEl = element;
|
||||
};
|
||||
|
||||
constructor(props: StencilReactInternalProps<ElementType>) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.componentDidUpdate(this.props);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: StencilReactInternalProps<ElementType>) {
|
||||
attachProps(this.componentEl, this.props, prevProps);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, forwardedRef, style, className, ref, ...cProps } = this.props;
|
||||
|
||||
let propsToPass = Object.keys(cProps).reduce((acc, name) => {
|
||||
if (name.indexOf('on') === 0 && name[2] === name[2].toUpperCase()) {
|
||||
const eventName = name.substring(2).toLowerCase();
|
||||
if (typeof document !== 'undefined' && isCoveredByReact(eventName)) {
|
||||
(acc as any)[name] = (cProps as any)[name];
|
||||
}
|
||||
} else {
|
||||
(acc as any)[name] = (cProps as any)[name];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
if (manipulatePropsFunction) {
|
||||
propsToPass = manipulatePropsFunction(this.props, propsToPass);
|
||||
}
|
||||
|
||||
const newProps: Omit<StencilReactInternalProps<ElementType>, 'forwardedRef'> = {
|
||||
...propsToPass,
|
||||
ref: mergeRefs(forwardedRef, this.setComponentElRef),
|
||||
style,
|
||||
};
|
||||
|
||||
return React.createElement(tagName, newProps, children);
|
||||
}
|
||||
|
||||
static get displayName() {
|
||||
return displayName;
|
||||
}
|
||||
};
|
||||
|
||||
// If context was passed to createReactComponent then conditionally add it to the Component Class
|
||||
if (ReactComponentContext) {
|
||||
ReactComponent.contextType = ReactComponentContext;
|
||||
}
|
||||
|
||||
return createForwardRef<PropType, ElementType>(ReactComponent, displayName);
|
||||
};
|
@ -0,0 +1,152 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { OverlayEventDetail } from './interfaces';
|
||||
import { StencilReactForwardedRef, attachProps, setRef } from './utils';
|
||||
|
||||
interface OverlayElement extends HTMLElement {
|
||||
present: () => Promise<void>;
|
||||
dismiss: (data?: any, role?: string | undefined) => Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface ReactOverlayProps {
|
||||
children?: React.ReactNode;
|
||||
isOpen: boolean;
|
||||
onDidDismiss?: (event: CustomEvent<OverlayEventDetail>) => void;
|
||||
onDidPresent?: (event: CustomEvent<OverlayEventDetail>) => void;
|
||||
onWillDismiss?: (event: CustomEvent<OverlayEventDetail>) => void;
|
||||
onWillPresent?: (event: CustomEvent<OverlayEventDetail>) => void;
|
||||
}
|
||||
|
||||
export const createOverlayComponent = <
|
||||
OverlayComponent extends object,
|
||||
OverlayType extends OverlayElement
|
||||
>(
|
||||
displayName: string,
|
||||
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?: StencilReactForwardedRef<OverlayType>;
|
||||
};
|
||||
|
||||
let isDismissing = false;
|
||||
|
||||
class Overlay extends React.Component<Props> {
|
||||
overlay?: OverlayType;
|
||||
el!: HTMLDivElement;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
if (typeof document !== 'undefined') {
|
||||
this.el = document.createElement('div');
|
||||
}
|
||||
this.handleDismiss = this.handleDismiss.bind(this);
|
||||
}
|
||||
|
||||
static get displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.isOpen) {
|
||||
this.present();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.overlay) {
|
||||
this.overlay.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
handleDismiss(event: CustomEvent<OverlayEventDetail<any>>) {
|
||||
if (this.props.onDidDismiss) {
|
||||
this.props.onDidDismiss(event);
|
||||
}
|
||||
setRef(this.props.forwardedRef, null)
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps: Props) {
|
||||
// Check if the overlay component is about to dismiss
|
||||
if (this.overlay && nextProps.isOpen !== this.props.isOpen && nextProps.isOpen === false) {
|
||||
isDismissing = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async componentDidUpdate(prevProps: Props) {
|
||||
if (this.overlay) {
|
||||
attachProps(this.overlay, this.props, prevProps);
|
||||
}
|
||||
|
||||
if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === true) {
|
||||
this.present(prevProps);
|
||||
}
|
||||
if (this.overlay && prevProps.isOpen !== this.props.isOpen && this.props.isOpen === false) {
|
||||
await this.overlay.dismiss();
|
||||
isDismissing = false;
|
||||
|
||||
/**
|
||||
* Now that the overlay is dismissed
|
||||
* we need to render again so that any
|
||||
* inner components will be unmounted
|
||||
*/
|
||||
this.forceUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
async present(prevProps?: 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),
|
||||
};
|
||||
|
||||
this.overlay = await controller.create({
|
||||
...elementProps,
|
||||
component: this.el,
|
||||
componentProps: {},
|
||||
});
|
||||
|
||||
setRef(this.props.forwardedRef, this.overlay);
|
||||
attachProps(this.overlay, elementProps, prevProps);
|
||||
|
||||
await this.overlay.present();
|
||||
}
|
||||
|
||||
render() {
|
||||
/**
|
||||
* Continue to render the component even when
|
||||
* overlay is dismissing otherwise component
|
||||
* will be hidden before animation is done.
|
||||
*/
|
||||
return ReactDOM.createPortal(this.props.isOpen || isDismissing ? this.props.children : null, this.el);
|
||||
}
|
||||
}
|
||||
|
||||
return React.forwardRef<OverlayType, Props>((props, ref) => {
|
||||
return <Overlay {...props} forwardedRef={ref} />;
|
||||
});
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
export { createReactComponent } from './createComponent';
|
||||
export { createOverlayComponent } from './createOverlayComponent';
|
@ -0,0 +1,34 @@
|
||||
// General types important to applications using stencil built components
|
||||
export interface EventEmitter<T = any> {
|
||||
emit: (data?: T) => CustomEvent<T>;
|
||||
}
|
||||
|
||||
export interface StyleReactProps {
|
||||
class?: string;
|
||||
className?: string;
|
||||
style?: { [key: string]: any };
|
||||
}
|
||||
|
||||
export interface OverlayEventDetail<T = any> {
|
||||
data?: T;
|
||||
role?: string;
|
||||
}
|
||||
|
||||
export interface OverlayInterface {
|
||||
el: HTMLElement;
|
||||
animated: boolean;
|
||||
keyboardClose: boolean;
|
||||
overlayIndex: number;
|
||||
presented: boolean;
|
||||
|
||||
enterAnimation?: any;
|
||||
leaveAnimation?: any;
|
||||
|
||||
didPresent: EventEmitter<void>;
|
||||
willPresent: EventEmitter<void>;
|
||||
willDismiss: EventEmitter<OverlayEventDetail>;
|
||||
didDismiss: EventEmitter<OverlayEventDetail>;
|
||||
|
||||
present(): Promise<void>;
|
||||
dismiss(data?: any, role?: string): Promise<boolean>;
|
||||
}
|
@ -28,11 +28,10 @@ export const attachProps = (node: HTMLElement, newProps: any, oldProps: any = {}
|
||||
syncEvent(node, eventNameLc, newProps[name]);
|
||||
}
|
||||
} else {
|
||||
(node as any)[name] = newProps[name];
|
||||
const propType = typeof newProps[name];
|
||||
if (propType === 'string') {
|
||||
node.setAttribute(camelToDashCase(name), newProps[name]);
|
||||
} else {
|
||||
(node as any)[name] = newProps[name];
|
||||
}
|
||||
}
|
||||
});
|
@ -0,0 +1,47 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { StyleReactProps } from '../interfaces';
|
||||
|
||||
export type StencilReactExternalProps<PropType, ElementType> = PropType &
|
||||
Omit<React.HTMLAttributes<ElementType>, 'style'> &
|
||||
StyleReactProps;
|
||||
|
||||
// This will be replaced with React.ForwardedRef when react-output-target is upgraded to React v17
|
||||
export type StencilReactForwardedRef<T> = ((instance: T | null) => void) | React.MutableRefObject<T | null> | null;
|
||||
|
||||
export const setRef = (ref: StencilReactForwardedRef<any> | React.Ref<any> | undefined, value: any) => {
|
||||
if (typeof ref === 'function') {
|
||||
ref(value)
|
||||
} else if (ref != null) {
|
||||
// Cast as a MutableRef so we can assign current
|
||||
(ref as React.MutableRefObject<any>).current = value
|
||||
}
|
||||
};
|
||||
|
||||
export const mergeRefs = (
|
||||
...refs: (StencilReactForwardedRef<any> | React.Ref<any> | undefined)[]
|
||||
): React.RefCallback<any> => {
|
||||
return (value: any) => {
|
||||
refs.forEach(ref => {
|
||||
setRef(ref, value)
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
export const createForwardRef = <PropType, ElementType>(
|
||||
ReactComponent: any,
|
||||
displayName: string,
|
||||
) => {
|
||||
const forwardRef = (
|
||||
props: StencilReactExternalProps<PropType, ElementType>,
|
||||
ref: StencilReactForwardedRef<ElementType>,
|
||||
) => {
|
||||
return <ReactComponent {...props} forwardedRef={ref} />;
|
||||
};
|
||||
forwardRef.displayName = displayName;
|
||||
|
||||
return React.forwardRef(forwardRef);
|
||||
};
|
||||
|
||||
export * from './attachProps';
|
||||
export * from './case';
|
34
packages/react/src/components/routing-proxies.ts
Normal file
34
packages/react/src/components/routing-proxies.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import type { JSX } from '@ionic/core';
|
||||
|
||||
import { createRoutingComponent } from './createRoutingComponent';
|
||||
import { HrefProps } from './hrefprops';
|
||||
|
||||
export const IonRouterLink = /*@__PURE__*/ createRoutingComponent<
|
||||
HrefProps<JSX.IonRouterLink>,
|
||||
HTMLIonRouterLinkElement
|
||||
>('ion-router-link');
|
||||
|
||||
export const IonButton = /*@__PURE__*/ createRoutingComponent<
|
||||
HrefProps<JSX.IonButton>,
|
||||
HTMLIonButtonElement
|
||||
>('ion-button');
|
||||
|
||||
export const IonCard = /*@__PURE__*/ createRoutingComponent<
|
||||
HrefProps<JSX.IonCard>,
|
||||
HTMLIonCardElement
|
||||
>('ion-card');
|
||||
|
||||
export const IonFabButton = /*@__PURE__*/ createRoutingComponent<
|
||||
HrefProps<JSX.IonFabButton>,
|
||||
HTMLIonFabButtonElement
|
||||
>('ion-fab-button');
|
||||
|
||||
export const IonItem = /*@__PURE__*/ createRoutingComponent<
|
||||
HrefProps<JSX.IonItem>,
|
||||
HTMLIonItemElement
|
||||
>('ion-item');
|
||||
|
||||
export const IonItemOption = /*@__PURE__*/ createRoutingComponent<
|
||||
HrefProps<JSX.IonItemOption>,
|
||||
HTMLIonItemOptionElement
|
||||
>('ion-item-option');
|
@ -27,28 +27,6 @@ export const createForwardRef = <PropType, ElementType>(
|
||||
return React.forwardRef(forwardRef);
|
||||
};
|
||||
|
||||
export const setRef = (ref: React.ForwardedRef<any> | React.Ref<any> | undefined, value: any) => {
|
||||
if (typeof ref === 'function') {
|
||||
ref(value)
|
||||
} else if (ref != null) {
|
||||
// Cast as a MutableRef so we can assign current
|
||||
(ref as React.MutableRefObject<any>).current = value
|
||||
}
|
||||
};
|
||||
|
||||
export const mergeRefs = (
|
||||
...refs: (React.ForwardedRef<any> | React.Ref<any> | undefined)[]
|
||||
): React.RefCallback<any> => {
|
||||
return (value: any) => {
|
||||
refs.forEach(ref => {
|
||||
setRef(ref, value)
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
export * from './attachProps';
|
||||
export * from './case';
|
||||
|
||||
export const isPlatform = (platform: Platforms) => {
|
||||
return isPlatformCore(window, platform);
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { OverlayEventDetail } from '@ionic/core';
|
||||
import { useMemo, useRef } from 'react';
|
||||
|
||||
import { attachProps } from '../components/utils';
|
||||
import { attachProps } from '../components/react-component-lib/utils';
|
||||
|
||||
import { HookOverlayOptions } from './HookOverlayOptions';
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { OverlayEventDetail } from '@ionic/core';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { attachProps } from '../components/utils';
|
||||
import { attachProps } from '../components/react-component-lib/utils';
|
||||
|
||||
import { HookOverlayOptions } from './HookOverlayOptions';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import { mergeRefs } from '../components/utils';
|
||||
import { mergeRefs } from '../components/react-component-lib/utils';
|
||||
import { IonLifeCycleContext } from '../contexts/IonLifeCycleContext';
|
||||
import { RouteInfo } from '../models';
|
||||
|
||||
|
Reference in New Issue
Block a user