/
githubmirror
/
ionic-framework
Обзор
Документация
Войти
/
githubmirror
/
ionic-framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/react/src/components/createRoutingComponent.tsx
113 строк
4 KB
Liam DeBeasi
chore(react): migrate to eslint, add prettier (#26633)
19 янв 2023, 00:49
Не верифицирован
19 янв 2023, 00:49
b02190d
Код
Авторство
О чём код?
import type { AnimationBuilder } from '@ionic/core/components'; import React, { createElement } from 'react'; import { NavContext } from '../contexts/NavContext'; import type { RouterOptions } from '../models'; import type { RouterDirection } from '../models/RouterDirection'; import { attachProps, camelToDashCase, dashToPascalCase, defineCustomElement, isCoveredByReact, mergeRefs, } from './react-component-lib/utils'; import { createForwardRef } from './utils'; // TODO(FW-2959): types interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<ElementType> { forwardedRef?: React.ForwardedRef<ElementType>; href?: string; routerLink?: string; ref?: React.Ref<any>; routerDirection?: RouterDirection; routerOptions?: RouterOptions; routerAnimation?: AnimationBuilder; } export const createRoutingComponent = <PropType, ElementType>(tagName: string, customElement?: any) => { defineCustomElement(tagName, customElement); const displayName = dashToPascalCase(tagName); const ReactComponent = class extends React.Component<IonicReactInternalProps<PropType>> { context!: React.ContextType<typeof NavContext>; ref: React.RefObject<HTMLElement>; stableMergedRefs: React.RefCallback<HTMLElement>; constructor(props: IonicReactInternalProps<PropType>) { super(props); // Create a local ref to to attach props to the wrapped element. this.ref = React.createRef(); // React refs must be stable (not created inline). this.stableMergedRefs = mergeRefs(this.ref, this.props.forwardedRef); } componentDidMount() { this.componentDidUpdate(this.props); } componentDidUpdate(prevProps: IonicReactInternalProps<PropType>) { const node = this.ref.current! as HTMLElement; attachProps(node, this.props, prevProps); } private handleClick = (e: React.MouseEvent<PropType>) => { const { routerLink, routerDirection, routerOptions, routerAnimation } = this.props; if (routerLink !== undefined) { e.preventDefault(); this.context.navigate(routerLink, routerDirection, undefined, routerAnimation, routerOptions); } }; render() { // eslint-disable-next-line @typescript-eslint/no-unused-vars 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]; } } else if (['string', 'boolean', 'number'].includes(typeof (cProps as any)[name])) { (acc as any)[camelToDashCase(name)] = (cProps as any)[name]; } return acc; }, {}); const newProps: IonicReactInternalProps<PropType> = { ...propsToPass, ref: this.stableMergedRefs, style, }; if (this.props.routerLink && !this.props.href) { newProps.href = this.props.routerLink; } if (newProps.onClick) { const oldClick = newProps.onClick; newProps.onClick = (e: React.MouseEvent<PropType>) => { oldClick(e); if (!e.defaultPrevented) { this.handleClick(e); } }; } else { newProps.onClick = this.handleClick; } return createElement(tagName, newProps, children); } static get displayName() { return displayName; } static get contextType() { return NavContext; } }; return createForwardRef<PropType, ElementType>(ReactComponent, displayName); };