0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(console): tab nav (#2471)

This commit is contained in:
Xiao Yijun 2022-11-21 10:38:38 +08:00 committed by GitHub
parent e56238e6b6
commit 27e236fda2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 76 additions and 26 deletions

View file

@ -1,27 +1,61 @@
@use '@/scss/underscore' as _;
.link {
font: var(--font-subhead-2);
.item {
display: flex;
align-items: center;
&:not(:last-child) {
margin-right: _.unit(6);
}
a {
display: inline-block;
color: var(--color-text-secondary);
text-decoration: none;
cursor: pointer;
padding-bottom: _.unit(1);
.link {
font: var(--font-subhead-2);
padding: _.unit(0.5) _.unit(1.5);
margin-bottom: _.unit(1);
border-radius: 4px;
a {
display: inline-block;
color: var(--color-text-secondary);
text-decoration: none;
cursor: pointer;
}
&:hover {
background-color: var(--color-hover-variant);
}
}
}
.selected {
color: var(--color-text-link);
border-bottom: 2px solid var(--color-text-link);
margin-bottom: -1px;
a {
.selected {
position: relative;
color: var(--color-text-link);
a {
color: var(--color-text-link);
}
&::after {
content: '';
display: block;
position: absolute;
// Note: link item's margin-bottom (_.unit(1)) + TabNav's border-bottom width (1px)
bottom: -5px;
left: 0;
right: 0;
border-top: 2px solid var(--color-text-link);
border-radius: 8px 8px 0 0;
}
}
.errors {
margin-left: _.unit(0.5);
font: var(--font-label-medium);
color: var(--color-white);
padding: _.unit(0.5) _.unit(1.5);
background-color: var(--color-error-50);
border-radius: 10px;
vertical-align: middle;
margin-bottom: _.unit(1);
}
}

View file

@ -1,4 +1,5 @@
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { Link, useLocation } from 'react-router-dom';
import { onKeyDownHandler } from '@/utilities/a11y';
@ -8,23 +9,30 @@ import * as styles from './TabNavItem.module.scss';
type Props = {
href?: string;
isActive?: boolean;
errorCount?: number;
onClick?: () => void;
children: React.ReactNode;
};
const TabNavItem = ({ children, href, isActive, onClick }: Props) => {
const TabNavItem = ({ children, href, isActive, errorCount = 0, onClick }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const location = useLocation();
const selected = href ? location.pathname === href : isActive;
return (
<div className={classNames(styles.link, selected && styles.selected)}>
{href ? (
<Link to={href}>{children}</Link>
) : (
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<a role="tab" tabIndex={0} onKeyDown={onKeyDownHandler(onClick)} onClick={onClick}>
{children}
</a>
<div className={styles.item}>
<div className={classNames(styles.link, selected && styles.selected)}>
{href ? (
<Link to={href}>{children}</Link>
) : (
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<a role="tab" tabIndex={0} onKeyDown={onKeyDownHandler(onClick)} onClick={onClick}>
{children}
</a>
)}
</div>
{errorCount > 0 && (
<div className={styles.errors}>{t('general.tab_errors', { count: errorCount })}</div>
)}
</div>
);

View file

@ -31,8 +31,9 @@
}
.nav {
padding: 0 _.unit(6);
margin: _.unit(6) 0 0 0;
padding: 0 _.unit(6) 1px;
margin-top: _.unit(6);
border-bottom: unset;
}
.body {

View file

@ -41,6 +41,7 @@ const general = {
got_it: 'Got it', // UNTRANSLATED
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
learn_more: 'Learn more', // UNTRANSLATED
tab_errors: '{{count, number}} errors', // UNTRANSLATED
};
export default general;

View file

@ -40,6 +40,7 @@ const general = {
got_it: 'Got it',
page_info: '{{min, number}}-{{max, number}} of {{total, number}}',
learn_more: 'Learn more',
tab_errors: '{{count, number}} errors',
};
export default general;

View file

@ -41,6 +41,7 @@ const general = {
got_it: 'Got it', // UNTRANSLATED
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
learn_more: 'Learn more', // UNTRANSLATED
tab_errors: '{{count, number}} errors', // UNTRANSLATED
};
export default general;

View file

@ -40,6 +40,7 @@ const general = {
got_it: 'Got it', // UNTRANSLATED
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
learn_more: 'Learn more', // UNTRANSLATED
tab_errors: '{{count, number}} errors', // UNTRANSLATED
};
export default general;

View file

@ -40,6 +40,7 @@ const general = {
got_it: 'Got it', // UNTRANSLATED
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
learn_more: 'Learn more', // UNTRANSLATED
tab_errors: '{{count, number}} errors', // UNTRANSLATED
};
export default general;

View file

@ -41,6 +41,7 @@ const general = {
got_it: 'Got it', // UNTRANSLATED
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
learn_more: 'Learn more', // UNTRANSLATED
tab_errors: '{{count, number}} errors', // UNTRANSLATED
};
export default general;

View file

@ -40,6 +40,7 @@ const general = {
got_it: 'Got it', // UNTRANSLATED
page_info: '{{min, number}}-{{max, number}} 共 {{total, number}} 条', // UNTRANSLATED
learn_more: 'Learn more', // UNTRANSLATED
tab_errors: '{{count, number}} errors', // UNTRANSLATED
};
export default general;