Add keyboard navigation for users, groups, branches, tags, sources, changesets and plugins (#2153)

Co-authored-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
This commit is contained in:
Konstantin Schaper
2022-11-10 11:44:53 +01:00
committed by GitHub
parent da71004dd0
commit eea60deadb
28 changed files with 819 additions and 373 deletions

View File

@@ -21,47 +21,49 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React from "react";
import { WithTranslation, withTranslation } from "react-i18next";
import React, { FC } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { User } from "@scm-manager/ui-types";
import { createAttributesForTesting, Icon } from "@scm-manager/ui-components";
import classNames from "classnames";
import { useKeyboardIteratorTarget } from "@scm-manager/ui-shortcuts";
type Props = WithTranslation & {
type Props = {
user: User;
};
class UserRow extends React.Component<Props> {
renderLink(to: string, label: string) {
return (
<Link to={to} {...createAttributesForTesting(label)}>
{label}
</Link>
);
}
const UserRowLink = React.forwardRef<HTMLAnchorElement, { to: string; children: string }>(({ children, to }, ref) => (
<Link ref={ref} to={to} {...createAttributesForTesting(children)}>
{children}
</Link>
));
const UserRow: FC<Props> = ({ user }) => {
const ref = useKeyboardIteratorTarget();
const [t] = useTranslation("users");
const to = `/user/${user.name}`;
const iconType = user.active ? (
<Icon title={t("user.active")} name="user" />
) : (
<Icon title={t("user.inactive")} name="user-slash" />
);
render() {
const { user, t } = this.props;
const to = `/user/${user.name}`;
const iconType = user.active ? (
<Icon title={t("user.active")} name="user" />
) : (
<Icon title={t("user.inactive")} name="user-slash" />
);
return (
<tr className={user.active ? "border-is-green" : "border-is-yellow"}>
<td className="is-word-break">
{iconType}{" "}
<UserRowLink ref={ref} to={to}>
{user.name}
</UserRowLink>
</td>
<td className={classNames("is-hidden-mobile", "is-word-break")}>
<UserRowLink to={to}>{user.displayName}</UserRowLink>
</td>
<td className={classNames("is-hidden-mobile", "is-word-break")}>
{user.mail ? <a href={`mailto:${user.mail}`}>{user.mail}</a> : null}
</td>
</tr>
);
};
return (
<tr className={user.active ? "border-is-green" : "border-is-yellow"}>
<td className="is-word-break">
{iconType} {this.renderLink(to, user.name)}
</td>
<td className={classNames("is-hidden-mobile", "is-word-break")}>{this.renderLink(to, user.displayName)}</td>
<td className={classNames("is-hidden-mobile", "is-word-break")}>
{user.mail ? <a href={`mailto:${user.mail}`}>{user.mail}</a> : null}
</td>
</tr>
);
}
}
export default withTranslation("users")(UserRow);
export default UserRow;