baseComponent.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /**
  2. * The Semi Foundation / Adapter architecture split was inspired by Material Component For Web. (https://github.com/material-components/material-components-web)
  3. * We re-implemented our own code based on the principle and added more functions we need according to actual needs.
  4. */
  5. import React, { Component, ReactNode } from 'react';
  6. import log from '@douyinfe/semi-foundation/utils/log';
  7. import { DefaultAdapter } from '@douyinfe/semi-foundation/base/foundation';
  8. import { VALIDATE_STATUS } from '@douyinfe/semi-foundation/base/constants';
  9. import getDataAttr from '@douyinfe/semi-foundation/utils/getDataAttr';
  10. import { ArrayElement } from './base';
  11. const { hasOwnProperty } = Object.prototype;
  12. export type ValidateStatus = ArrayElement<typeof VALIDATE_STATUS>;
  13. export interface BaseProps {
  14. style?: React.CSSProperties;
  15. className?: string;
  16. children?: ReactNode | undefined | any
  17. }
  18. // eslint-disable-next-line
  19. export default class BaseComponent<P extends BaseProps = {}, S = {}> extends Component<P, S> {
  20. static propTypes = {};
  21. static defaultProps = {};
  22. cache: any;
  23. foundation: any;
  24. constructor(props: P) {
  25. super(props);
  26. this.cache = {};
  27. this.foundation = null;
  28. }
  29. componentDidMount(): void {
  30. this.foundation && typeof this.foundation.init === 'function' && this.foundation.init();
  31. }
  32. componentWillUnmount(): void {
  33. this.foundation && typeof this.foundation.destroy === 'function' && this.foundation.destroy();
  34. this.cache = {};
  35. }
  36. get adapter(): DefaultAdapter<P, S> { // eslint-disable-line
  37. return {
  38. getContext: key => { // eslint-disable-line
  39. if (this.context && key) {
  40. return this.context[key];
  41. }
  42. },
  43. getContexts: () => this.context, // eslint-disable-line
  44. getProp: key => this.props[key], // eslint-disable-line
  45. // return all props
  46. getProps: () => this.props, // eslint-disable-line
  47. getState: key => this.state[key], // eslint-disable-line
  48. getStates: () => this.state, // eslint-disable-line
  49. setState: (states, cb) => this.setState({ ...states } as S, cb), // eslint-disable-line
  50. getCache: key => key && this.cache[key], // eslint-disable-line
  51. getCaches: () => this.cache, // eslint-disable-line
  52. setCache: (key, value) => key && (this.cache[key] = value), // eslint-disable-line
  53. stopPropagation: e => { // eslint-disable-line
  54. try {
  55. e.stopPropagation();
  56. e.nativeEvent && e.nativeEvent.stopImmediatePropagation();
  57. } catch (error) {
  58. }
  59. },
  60. persistEvent: (e: React.KeyboardEvent | React.MouseEvent) => {
  61. e && e.persist && typeof e.persist === 'function' ? e.persist() : null;
  62. }
  63. };
  64. }
  65. // eslint-disable-next-line
  66. isControlled = (key: any) => Boolean(key && this.props && typeof this.props === 'object' && hasOwnProperty.call(this.props, key));
  67. log(text: string, ...rest: any): any {
  68. return log(text, ...rest);
  69. }
  70. getDataAttr(props: any = this.props) {
  71. return getDataAttr(props);
  72. }
  73. setStateAsync = (state: Partial<S>)=>{
  74. return new Promise<void>(resolve=>{
  75. this.setState(state as any, resolve);
  76. });
  77. }
  78. }