- The Pupil Platform has been developed by Laboratory for Neuroinfomatics, RIKEN Brain Science Institute in 2007.
- Which is the one of the practical applications of XooNIps base platform system.
- For more inforamtion, see related publication below.
+ The Pupil Platform has been developed by Laboratory for Neuroinfomatics, RIKEN Brain Science
+ Institute in 2007. Which is the one of the practical applications of{' '}
+
+ XooNIps base platform system
+
+ . For more inforamtion, see related publication below.
Related Publication
- Customizable neuroinformatics database system: XooNIps and its application to the pupil platform. Yamaji K, Sakai H, Okumura Y, Usui S
-Comput Biol Med. 37(7) 1036-1041 Jul 2007
+ Customizable neuroinformatics database system: XooNIps and its application to the pupil platform. Yamaji
+ K, Sakai H, Okumura Y, Usui S Comput Biol Med. 37(7) 1036-1041 Jul 2007
- https://doi.org/10.1016/j.compbiomed.2006.09.003
+
+ https://doi.org/10.1016/j.compbiomed.2006.09.003
+
);
-}
+};
-export default MainContent;
\ No newline at end of file
+export default MainContent;
diff --git a/src/common/RightColumn.module.css b/src/common/RightColumn.module.css
index 4b96f1b..a58111b 100644
--- a/src/common/RightColumn.module.css
+++ b/src/common/RightColumn.module.css
@@ -1,5 +1,6 @@
.rightColumn {
- width: 200px;
+ /* border-box: 200 plus the 12px of left padding */
+ width: 212px;
padding-left: 12px;
}
@@ -29,4 +30,4 @@
.rightBlockContent a:hover {
color: #ff6600;
-}
\ No newline at end of file
+}
diff --git a/src/common/RightColumn.tsx b/src/common/RightColumn.tsx
index 0a4f3e1..9246294 100644
--- a/src/common/RightColumn.tsx
+++ b/src/common/RightColumn.tsx
@@ -1,5 +1,4 @@
-import React from 'react';
-import { MultiLang } from '../config';
+import type { MultiLang } from '../config';
import FlickrBadge from '../custom/blocks/FlickrBadge';
import styles from './RightColumn.module.css';
@@ -7,18 +6,17 @@ interface Props {
lang: MultiLang;
}
-const RightColumn = (props: Props) => {
- const { lang } = props;
+const RightColumn = (_props: Props) => {
return (
Eye Photos
-
+
);
-}
+};
-export default RightColumn;
\ No newline at end of file
+export default RightColumn;
diff --git a/src/common/XoopsPathRedirect.tsx b/src/common/XoopsPathRedirect.tsx
index 44ce26c..16ef2f0 100644
--- a/src/common/XoopsPathRedirect.tsx
+++ b/src/common/XoopsPathRedirect.tsx
@@ -1,44 +1,30 @@
-import React, { Component } from 'react';
-import { Redirect, RouteComponentProps } from 'react-router';
-import { MultiLang } from '../config';
+import { Navigate, useLocation } from 'react-router';
+import type { MultiLang } from '../config';
import PageNotFound from './lib/PageNotFound';
-interface Params {
- module: string;
- pathname: string;
-}
-
-interface Props extends RouteComponentProps {
+interface Props {
lang: MultiLang;
}
-class XoopsPathRedirect extends Component {
-
- getRedirectUrl() {
- const { pathname } = this.props.location;
- switch (pathname || '') {
- case '/index.php': {
- return '/';
- }
- case '/modules/mailform':
- case '/modules/mailform/index.php': {
- return '/about';
- }
- }
- return '';
+const getRedirectUrl = (pathname: string): string => {
+ switch (pathname || '') {
+ case '/index.php':
+ return '/';
}
+ return '';
+};
- render() {
- const { lang } = this.props;
- if (this.props.location.pathname === '/') {
- return null;
- }
- const url = this.getRedirectUrl();
- if (url === '') {
- return ;
- }
- return ;
+const XoopsPathRedirect = (props: Props) => {
+ const { lang } = props;
+ const location = useLocation();
+ if (location.pathname === '/') {
+ return null;
}
-}
+ const url = getRedirectUrl(location.pathname);
+ if (url === '') {
+ return ;
+ }
+ return ;
+};
export default XoopsPathRedirect;
diff --git a/src/common/blocks/MainMenu.module.css b/src/common/blocks/MainMenu.module.css
index a28aa13..b01d848 100644
--- a/src/common/blocks/MainMenu.module.css
+++ b/src/common/blocks/MainMenu.module.css
@@ -27,4 +27,4 @@
.menuSub {
padding-left: 1em;
-}
\ No newline at end of file
+}
diff --git a/src/common/blocks/MainMenu.tsx b/src/common/blocks/MainMenu.tsx
index 4a51792..31ada59 100644
--- a/src/common/blocks/MainMenu.tsx
+++ b/src/common/blocks/MainMenu.tsx
@@ -1,20 +1,26 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import { MultiLang } from '../../config';
+import { Link } from 'react-router';
import styles from './MainMenu.module.css';
-interface Props {
- lang: MultiLang;
-}
-
-const MainMenu = (props: Props) => {
+const MainMenu = () => {
return (
-
Home
-
Database
-
About
+
+
+ Home
+
+
+
+
+ Database
+
+
+
+
+ About
+
+
);
-}
+};
export default MainMenu;
diff --git a/src/common/lib/HashLink.tsx b/src/common/lib/HashLink.tsx
new file mode 100644
index 0000000..14ebd2e
--- /dev/null
+++ b/src/common/lib/HashLink.tsx
@@ -0,0 +1,53 @@
+import type { ComponentProps, MouseEvent } from 'react';
+import { Link, type To } from 'react-router';
+
+type LinkProps = ComponentProps;
+
+const RETRY_INTERVAL_MS = 16;
+const RETRY_COUNT = 20;
+
+const hashOf = (to: To): string => {
+ if (typeof to === 'string') {
+ const idx = to.indexOf('#');
+ return idx === -1 ? '' : to.slice(idx + 1);
+ }
+ return (to.hash ?? '').replace(/^#/, '');
+};
+
+const scrollToHash = (hash: string, remaining = RETRY_COUNT) => {
+ if (hash === '') {
+ return;
+ }
+ const id = decodeURIComponent(hash);
+ const target = document.getElementById(id) ?? document.querySelector(`[name="${CSS.escape(id)}"]`);
+ if (target !== null) {
+ target.scrollIntoView();
+ return;
+ }
+ // The target may not be in the DOM yet (pico pages fetch their content).
+ if (remaining > 0) {
+ setTimeout(() => {
+ scrollToHash(hash, remaining - 1);
+ }, RETRY_INTERVAL_MS);
+ }
+};
+
+/**
+ * A `` that also scrolls to the element named by the URL fragment.
+ * Replaces `react-router-hash-link`, which is unmaintained and still targets react-router v5.
+ */
+const HashLink = ({ onClick, to, ...rest }: LinkProps) => {
+ const handleClick = (e: MouseEvent) => {
+ onClick?.(e);
+ if (e.defaultPrevented) {
+ return;
+ }
+ // Let react-router commit the navigation before looking for the target.
+ setTimeout(() => {
+ scrollToHash(hashOf(to));
+ }, 0);
+ };
+ return ;
+};
+
+export default HashLink;
diff --git a/src/common/lib/LangFlag.tsx b/src/common/lib/LangFlag.tsx
index 191fb21..784c3fa 100644
--- a/src/common/lib/LangFlag.tsx
+++ b/src/common/lib/LangFlag.tsx
@@ -1,11 +1,9 @@
-import React from 'react';
-import { RouteComponentProps, withRouter } from 'react-router';
-import { Link } from 'react-router-dom';
-import { MultiLang } from '../../config';
+import { Link, useLocation } from 'react-router';
+import type { MultiLang } from '../../config';
import mlangEnglish from '../assets/images/mlang_english.gif';
import mlangJapanese from '../assets/images/mlang_japanese.gif';
-interface Props extends RouteComponentProps {
+interface Props {
lang: MultiLang;
}
@@ -23,16 +21,21 @@ const langResources = {
const LangFlag = (props: Props) => {
const { lang } = props;
- const params = new URLSearchParams(props.location.search);
+ const location = useLocation();
+ const params = new URLSearchParams(location.search);
const flagLang = lang === 'en' ? 'ja' : 'en';
params.set('ml_lang', flagLang);
- const url = props.location.pathname + '?' + params.toString();
+ const url = `${location.pathname}?${params.toString()}`;
return (
-
+
);
-}
+};
-
-export default withRouter(LangFlag);
+export default LangFlag;
diff --git a/src/common/lib/LinkImage.tsx b/src/common/lib/LinkImage.tsx
index 251e2cb..7581759 100644
--- a/src/common/lib/LinkImage.tsx
+++ b/src/common/lib/LinkImage.tsx
@@ -1,5 +1,5 @@
-import React, { Component } from 'react';
-import { Link } from 'react-router-dom';
+import { Component } from 'react';
+import { Link } from 'react-router';
interface Props {
url: string;
@@ -13,7 +13,6 @@ interface State {
}
class LinkImage extends Component {
-
constructor(props: Props) {
super(props);
this.state = {
@@ -26,14 +25,14 @@ class LinkImage extends Component {
handleMouseOver() {
const { imageHover } = this.props;
if (typeof imageHover !== 'undefined') {
- this.setState({ image: imageHover })
+ this.setState({ image: imageHover });
}
}
handleMouseOut() {
const { image: imageNormal, imageHover } = this.props;
if (typeof imageHover !== 'undefined') {
- this.setState({ image: imageNormal })
+ this.setState({ image: imageNormal });
}
}
@@ -42,13 +41,27 @@ class LinkImage extends Component {
const image = ;
if (url.match(/^(\/|\.)/) === null) {
return (
-
+
{image}
);
}
return (
-
+
{image}
);
diff --git a/src/common/lib/Loading.module.css b/src/common/lib/Loading.module.css
new file mode 100644
index 0000000..a339bdc
--- /dev/null
+++ b/src/common/lib/Loading.module.css
@@ -0,0 +1,27 @@
+.container {
+ display: flex;
+ justify-content: center;
+ align-content: center;
+ margin: 100px 0;
+}
+
+.spinner {
+ width: 120px;
+ height: 120px;
+ border: 8px solid #eeeeee;
+ border-top-color: #cccccc;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .spinner {
+ animation-duration: 4s;
+ }
+}
diff --git a/src/common/lib/Loading.tsx b/src/common/lib/Loading.tsx
index 13ec917..af664c3 100644
--- a/src/common/lib/Loading.tsx
+++ b/src/common/lib/Loading.tsx
@@ -1,12 +1,9 @@
-import React from 'react';
-import Spinner from 'react-spinner-material';
+import styles from './Loading.module.css';
-const Loading = () => {
- return (
-
-
-
- );
-}
+const Loading = () => (
+
+
+
+);
-export default Loading;
\ No newline at end of file
+export default Loading;
diff --git a/src/common/lib/NoticeSiteHasBeenArchived.tsx b/src/common/lib/NoticeSiteHasBeenArchived.tsx
index c44a297..a9546dd 100644
--- a/src/common/lib/NoticeSiteHasBeenArchived.tsx
+++ b/src/common/lib/NoticeSiteHasBeenArchived.tsx
@@ -1,5 +1,4 @@
-import React from 'react';
-import { MultiLang } from '../../config';
+import type { MultiLang } from '../../config';
import Functions from '../../functions';
interface Props {
@@ -8,8 +7,9 @@ interface Props {
const NoticeSiteHasBeenArchived = (props: Props) => {
const { lang } = props;
- const notice = '[en]This site has been archived since FY2019 and is no longer updated.[/en][ja]このサイトは、2019年度よりアーカイブサイトとして運用されています。[/ja]';
+ const notice =
+ '[en]This site has been archived since FY2019 and is no longer updated.[/en][ja]このサイトは、2019年度よりアーカイブサイトとして運用されています。[/ja]';
return