mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
Master react (#18998)
* chore(): bump to beta 8 * fix(): IonFabButton href fix * fix(react): support components with href attributes * fix(): Prep work to break router out * fix(): breaking react-router and react-core into own packages * chore(): moving view stuff out of react-core * chore(): dev build 8-1 * chore(): update to react beta 8 * chore(): fixes to deps * fix(): removing IonAnchor in favor of IonRouterLink * chore(): beta 9 release * refactor(react): treeshake, minify, api * wip * fix(): react dev builds * fix(): fixes to get app builds working again * fix(): removing tgz file * feat(): adding platform helper methods * fix(): don't map attributes to props * chore(): add test app * feat(): copy css folder from core * chore(): move rollup node resolve to devDependencies * fix(): expose setupConfig() * perf(): improve treeshaking * fix(): removing crypto from generateUniqueId * fix(): adding missing rollup dp * fix(): test cleanup and fixes to make tests pass * chore(): moving react to packages folder * fix(): fixing react build due to move to packages * feat(): adding missing IonInfiniteScrollContent component * chore(): add automated testing using cypress * fix(): adding option onDidDismiss to controller components * 0.0.10 react * wip * fix(): removing deprecated React calls * fix(): exporting setupConfig from core * chore(): bump to 4.8.0-rc.0 * chore(): updating test-app deps and fixing test * chore(): updates to react readme
This commit is contained in:
101
packages/react/src/components/createComponent.tsx
Normal file
101
packages/react/src/components/createComponent.tsx
Normal file
@ -0,0 +1,101 @@
|
||||
import { RouterDirection } from '@ionic/core';
|
||||
import React from 'react';
|
||||
import ReactDom from 'react-dom';
|
||||
|
||||
import { NavContext } from '../contexts/NavContext';
|
||||
|
||||
import { ReactProps } from './ReactProps';
|
||||
import { attachEventProps, createForwardRef, dashToPascalCase, isCoveredByReact } from './utils';
|
||||
|
||||
interface IonicReactInternalProps<ElementType> {
|
||||
forwardedRef?: React.Ref<ElementType>;
|
||||
children?: React.ReactNode;
|
||||
href?: string;
|
||||
target?: string;
|
||||
style?: string;
|
||||
ref?: React.Ref<any>;
|
||||
routerDirection?: RouterDirection;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const createReactComponent = <PropType, ElementType>(
|
||||
tagName: string,
|
||||
hrefComponent = false
|
||||
) => {
|
||||
const displayName = dashToPascalCase(tagName);
|
||||
const ReactComponent = class extends React.Component<IonicReactInternalProps<ElementType>> {
|
||||
context!: React.ContextType<typeof NavContext>;
|
||||
|
||||
constructor(props: IonicReactInternalProps<ElementType>) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.componentDidUpdate(this.props);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: IonicReactInternalProps<ElementType>) {
|
||||
const node = ReactDom.findDOMNode(this) as HTMLElement;
|
||||
attachEventProps(node, this.props, prevProps);
|
||||
}
|
||||
|
||||
private handleClick = (e: MouseEvent) => {
|
||||
// TODO: review target usage
|
||||
const { href, routerDirection } = this.props;
|
||||
if (href !== undefined && this.context.hasIonicRouter()) {
|
||||
e.preventDefault();
|
||||
this.context.navigate(href, routerDirection);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, forwardedRef, style, className, ref, ...cProps } = this.props;
|
||||
|
||||
const propsToPass = Object.keys(cProps).reduce((acc, name) => {
|
||||
if (name.indexOf('on') === 0 && name[2] === name[2].toUpperCase()) {
|
||||
const eventName = name.substring(2).toLowerCase();
|
||||
if (isCoveredByReact(eventName)) {
|
||||
(acc as any)[name] = (cProps as any)[name];
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const newProps: any = {
|
||||
...propsToPass,
|
||||
ref: forwardedRef,
|
||||
style,
|
||||
className
|
||||
};
|
||||
|
||||
if (hrefComponent) {
|
||||
if (newProps.onClick) {
|
||||
const oldClick = newProps.onClick;
|
||||
newProps.onClick = (e: MouseEvent) => {
|
||||
oldClick(e);
|
||||
if (!e.defaultPrevented) {
|
||||
this.handleClick(e);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
newProps.onClick = this.handleClick;
|
||||
}
|
||||
}
|
||||
|
||||
return React.createElement(
|
||||
tagName,
|
||||
newProps,
|
||||
children
|
||||
);
|
||||
}
|
||||
|
||||
static get displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
static get contextType() {
|
||||
return NavContext;
|
||||
}
|
||||
};
|
||||
return createForwardRef<PropType & ReactProps, ElementType>(ReactComponent, displayName);
|
||||
};
|
Reference in New Issue
Block a user