Просмотр исходного кода

Merge pull request #6557 from weseek/support/typescriptize-lsx-page

support: tpescriptize lsx page
Yuki Takei 3 лет назад
Родитель
Сommit
74bc6d03bf

+ 0 - 109
packages/plugin-lsx/src/components/LsxPageList/LsxPage.jsx

@@ -1,109 +0,0 @@
-import React from 'react';
-
-import { pathUtils } from '@growi/core';
-import { PageListMeta } from '@growi/ui';
-import PropTypes from 'prop-types';
-
-import { PageNode } from '../PageNode';
-import { LsxContext } from '../lsx-context';
-
-import { PagePathWrapper } from './PagePathWrapper';
-
-export class LsxPage extends React.Component {
-
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      isExists: false,
-      isLinkable: false,
-      hasChildren: false,
-    };
-  }
-
-  UNSAFE_componentWillMount() {
-    const pageNode = this.props.pageNode;
-
-    if (pageNode.page !== undefined) {
-      this.setState({ isExists: true });
-    }
-    if (pageNode.children.length > 0) {
-      this.setState({ hasChildren: true });
-    }
-
-    // process depth option
-    const optDepth = this.props.lsxContext.getOptDepth();
-    if (optDepth == null) {
-      this.setState({ isLinkable: true });
-    }
-    else {
-      const depth = this.props.depth;
-
-      // debug
-      // console.log(pageNode.pagePath, {depth, decGens, 'optDepth.start': optDepth.start, 'optDepth.end': optDepth.end});
-
-      const isLinkable = optDepth.start <= depth;
-      this.setState({ isLinkable });
-    }
-  }
-
-  getChildPageElement() {
-    const pageNode = this.props.pageNode;
-
-    let element = '';
-
-    // create child pages elements
-    if (this.state.hasChildren) {
-      const pages = pageNode.children.map((pageNode) => {
-        return (
-          <LsxPage
-            key={pageNode.pagePath}
-            depth={this.props.depth + 1}
-            pageNode={pageNode}
-            lsxContext={this.props.lsxContext}
-            basisViewersCount={this.props.basisViewersCount}
-          />
-        );
-      });
-
-      element = <ul className="page-list-ul">{pages}</ul>;
-    }
-
-    return element;
-  }
-
-  getIconElement() {
-    return (this.state.isExists)
-      ? <i className="ti ti-agenda" aria-hidden="true"></i>
-      : <i className="ti ti-file lsx-page-not-exist" aria-hidden="true"></i>;
-  }
-
-  render() {
-    const { pageNode, basisViewersCount } = this.props;
-
-    // create PagePath element
-    let pagePathNode = <PagePathWrapper pagePath={pageNode.pagePath} isExists={this.state.isExists} />;
-    if (this.state.isLinkable) {
-      pagePathNode = <a className="page-list-link" href={encodeURI(pathUtils.removeTrailingSlash(pageNode.pagePath))}>{pagePathNode}</a>;
-    }
-
-    // create PageListMeta element
-    const pageListMeta = (this.state.isExists) ? <PageListMeta page={pageNode.page} basisViewersCount={basisViewersCount} /> : '';
-
-    return (
-      <li className="page-list-li">
-        <small>{this.getIconElement()}</small> {pagePathNode}
-        <span className="ml-2">{pageListMeta}</span>
-        {this.getChildPageElement()}
-      </li>
-    );
-  }
-
-}
-
-LsxPage.propTypes = {
-  pageNode: PropTypes.instanceOf(PageNode).isRequired,
-  lsxContext: PropTypes.instanceOf(LsxContext).isRequired,
-  depth: PropTypes.number,
-  basisViewersCount: PropTypes.number,
-};

+ 95 - 0
packages/plugin-lsx/src/components/LsxPageList/LsxPage.tsx

@@ -0,0 +1,95 @@
+import React, { useMemo } from 'react';
+
+import { pathUtils } from '@growi/core';
+import { PagePathLabel, PageListMeta } from '@growi/ui';
+
+import { PageNode } from '../PageNode';
+import { LsxContext } from '../lsx-context';
+
+
+type Props = {
+  pageNode: PageNode,
+  lsxContext: LsxContext,
+  depth: number,
+  basisViewersCount?: number,
+};
+
+export const LsxPage = React.memo((props: Props): JSX.Element => {
+  const {
+    pageNode, lsxContext, depth, basisViewersCount,
+  } = props;
+
+  const isExists = pageNode.page !== undefined;
+  const isLinkable = (() => {
+    // process depth option
+    const optDepth = lsxContext.getOptDepth();
+    if (optDepth == null) {
+      return true;
+    }
+
+    // debug
+    // console.log(pageNode.pagePath, {depth, decGens, 'optDepth.start': optDepth.start, 'optDepth.end': optDepth.end});
+
+    return optDepth.start <= depth;
+  })();
+  const hasChildren = pageNode.children.length > 0;
+
+  const childrenElements: JSX.Element = useMemo(() => {
+    let element = <></>;
+
+    // create child pages elements
+    if (hasChildren) {
+      const pages = pageNode.children.map((pageNode) => {
+        return (
+          <LsxPage
+            key={pageNode.pagePath}
+            depth={depth + 1}
+            pageNode={pageNode}
+            lsxContext={lsxContext}
+            basisViewersCount={basisViewersCount}
+          />
+        );
+      });
+
+      element = <ul className="page-list-ul">{pages}</ul>;
+    }
+
+    return element;
+  }, [basisViewersCount, depth, hasChildren, lsxContext, pageNode.children]);
+
+  const iconElement: JSX.Element = useMemo(() => {
+    return (isExists)
+      ? <i className="ti ti-agenda" aria-hidden="true"></i>
+      : <i className="ti ti-file lsx-page-not-exist" aria-hidden="true"></i>;
+  }, [isExists]);
+
+  const pagePathElement: JSX.Element = useMemo(() => {
+    const classNames: string[] = [];
+    if (!isExists) {
+      classNames.push('lsx-page-not-exist');
+    }
+
+    // create PagePath element
+    let pagePathNode = <PagePathLabel path={pageNode.pagePath} isLatterOnly additionalClassNames={classNames} />;
+    if (isLinkable) {
+      pagePathNode = <a className="page-list-link" href={encodeURI(pathUtils.removeTrailingSlash(pageNode.pagePath))}>{pagePathNode}</a>;
+    }
+    return pagePathNode;
+  }, [isExists, isLinkable, pageNode.pagePath]);
+
+  const pageListMetaElement: JSX.Element = useMemo(() => {
+    if (!isExists) {
+      return <></>;
+    }
+    return <PageListMeta page={pageNode.page} basisViewersCount={basisViewersCount} />;
+  }, [basisViewersCount, isExists, pageNode.page]);
+
+  return (
+    <li className="page-list-li">
+      <small>{iconElement}</small> {pagePathElement}
+      <span className="ml-2">{pageListMetaElement}</span>
+      {childrenElements}
+    </li>
+  );
+
+});

+ 0 - 31
packages/plugin-lsx/src/components/LsxPageList/PagePathWrapper.jsx

@@ -1,31 +0,0 @@
-import React from 'react';
-
-import { PagePathLabel } from '@growi/ui';
-import PropTypes from 'prop-types';
-
-
-export class PagePathWrapper extends React.Component {
-
-  render() {
-
-    const classNames = [];
-    if (!this.props.isExists) {
-      classNames.push('lsx-page-not-exist');
-    }
-
-    return (
-      <PagePathLabel path={this.props.pagePath} isLatterOnly additionalClassNames={classNames} />
-    );
-  }
-
-}
-
-PagePathWrapper.propTypes = {
-  pagePath: PropTypes.string.isRequired,
-  isExists: PropTypes.bool.isRequired,
-  excludePathString: PropTypes.string,
-};
-
-PagePathWrapper.defaultProps = {
-  excludePathString: '',
-};