Skip to content

Commit

Permalink
Replace manual DOM ids with useId()
Browse files Browse the repository at this point in the history
Closes #670
  • Loading branch information
owi92 committed Oct 25, 2023
1 parent 2877f3c commit ee465af
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 27 deletions.
16 changes: 9 additions & 7 deletions frontend/src/routes/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactNode, useState } from "react";
import React, { ReactNode, useId, useState } from "react";
import { useTranslation } from "react-i18next";
import { graphql, usePreloadedQuery } from "react-relay";
import type { PreloadedQuery } from "react-relay";
Expand Down Expand Up @@ -126,8 +126,10 @@ const LoginBox: React.FC = () => {
const { t, i18n } = useTranslation();
const isDark = useColorScheme().scheme === "dark";
const { register, handleSubmit, watch, formState: { errors } } = useForm<FormData>();
const userid = watch("userid", "");
const userId = watch("userid", "");
const password = watch("password", "");
const userFieldId = useId();
const passwordFieldId = useId();

const validation = { required: t("general.form.this-field-is-required") };

Expand Down Expand Up @@ -195,14 +197,14 @@ const LoginBox: React.FC = () => {
}}
>
<div>
<Field isEmpty={userid === ""}>
<label htmlFor="userid">
<Field isEmpty={userId === ""}>
<label htmlFor={userFieldId}>
{CONFIG.auth.userIdLabel
? translatedConfig(CONFIG.auth.userIdLabel, i18n)
: t("login-page.user-id")}
</label>
<input
id="userid"
id={userFieldId}
autoComplete="username email"
spellCheck={false}
autoCapitalize="none"
Expand All @@ -215,13 +217,13 @@ const LoginBox: React.FC = () => {
</div>
<div>
<Field isEmpty={password === ""}>
<label htmlFor="password">
<label htmlFor={passwordFieldId}>
{CONFIG.auth.passwordLabel
? translatedConfig(CONFIG.auth.passwordLabel, i18n)
: t("login-page.password")}
</label>
<input
id="password"
id={passwordFieldId}
type="password"
autoComplete="current-password"
required
Expand Down
16 changes: 10 additions & 6 deletions frontend/src/routes/Upload.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { MutableRefObject, ReactNode, useEffect, useRef, useState } from "react";
import React, { MutableRefObject, ReactNode, useEffect, useId, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { graphql, useFragment } from "react-relay";
import { keyframes } from "@emotion/react";
Expand Down Expand Up @@ -674,6 +674,9 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole
const { t } = useTranslation();
const user = useUser();
const userRole = getUserRole(user);
const titleFieldId = useId();
const descriptionFieldId = useId();
const seriesFieldId = useId();

const defaultAcl: Acl = {
readRoles: new Set([COMMON_ROLES.ANONYMOUS, userRole]),
Expand Down Expand Up @@ -711,9 +714,9 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole
>
{/* Title */}
<InputContainer>
<TitleLabel htmlFor="title-field" />
<TitleLabel htmlFor={titleFieldId} />
<Input
id="title-field"
id={titleFieldId}
required
error={!!errors.title}
css={{ width: 400, maxWidth: "100%" }}
Expand All @@ -727,13 +730,13 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole

{/* Description */}
<InputContainer>
<label htmlFor="description-field">{t("upload.metadata.description")}</label>
<TextArea id="description-field" {...register("description")} />
<label htmlFor={descriptionFieldId}>{t("upload.metadata.description")}</label>
<TextArea id={descriptionFieldId} {...register("description")} />
</InputContainer>

{/* Series */}
<InputContainer>
<label htmlFor="series-field">
<label htmlFor={seriesFieldId}>
{t("series.series")}
{CONFIG.upload.requireSeries && <FieldIsRequiredNote />}
<WithTooltip
Expand All @@ -750,6 +753,7 @@ const MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled, knownRole
</WithTooltip>
</label>
<SeriesSelector
inputId={seriesFieldId}
writableOnly
menuPlacement="top"
onChange={data => seriesField.onChange(data?.opencastId)}
Expand Down
12 changes: 7 additions & 5 deletions frontend/src/routes/manage/Realm/AddChild.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactNode, useState } from "react";
import React, { ReactNode, useId, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { graphql, useMutation } from "react-relay";

Expand Down Expand Up @@ -101,6 +101,8 @@ type Props = {

const AddChild: React.FC<Props> = ({ parent }) => {
const { t } = useTranslation();
const nameFieldId = useId();
const pathFieldId = useId();

type FormData = {
name: string;
Expand Down Expand Up @@ -162,10 +164,10 @@ const AddChild: React.FC<Props> = ({ parent }) => {
}}
>
<InputWithInfo info={t("manage.add-child.page-name-info")}>
<label htmlFor="name-field">{t("manage.realm.general.page-name")}</label>
<label htmlFor={nameFieldId}>{t("manage.realm.general.page-name")}</label>
<div>
<Input
id="name-field"
id={nameFieldId}
placeholder={t("manage.realm.general.page-name")}
error={!!errors.name}
autoFocus
Expand All @@ -181,9 +183,9 @@ const AddChild: React.FC<Props> = ({ parent }) => {
{{ reservedChars: RESERVED_CHARS }}
</Trans>}
>
<label htmlFor="path-field">{t("manage.add-child.path-segment")}</label>
<label htmlFor={pathFieldId}>{t("manage.add-child.path-segment")}</label>
<PathSegmentInput
id="path-field"
id={pathFieldId}
base={parent.path}
error={!!errors.pathSegment}
{...register("pathSegment", validations.path)}
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/routes/manage/Realm/General.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next";
import { graphql, useFragment, useMutation } from "react-relay";
import { useState } from "react";
import { useId, useState } from "react";
import { bug, match } from "@opencast/appkit";

import type {
Expand Down Expand Up @@ -86,6 +86,8 @@ type NameFormProps = {
};

export const NameForm: React.FC<NameFormProps> = ({ realm }) => {
const plainInputFieldId = useId();

type FormData = {
name: string | null;
block: string | null;
Expand Down Expand Up @@ -203,7 +205,7 @@ export const NameForm: React.FC<NameFormProps> = ({ realm }) => {
</label>
{isPlain && <div>
<Input
id="rename-field"
id={plainInputFieldId}
defaultValue={realm.name ?? ""}
error={!!errors.name}
css={{ width: 500, maxWidth: "100%" }}
Expand Down
12 changes: 7 additions & 5 deletions frontend/src/routes/manage/Video/Details.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useTranslation } from "react-i18next";
import { FiExternalLink } from "react-icons/fi";

import { useState } from "react";
import { useId, useState } from "react";
import { Link } from "../../../router";
import { NotAuthorized } from "../../../ui/error";
import { Form } from "../../../ui/Form";
Expand Down Expand Up @@ -133,24 +133,26 @@ const DateValue: React.FC<DateValueProps> = ({ label, value }) => (

const MetadataSection: React.FC<Props> = ({ event }) => {
const { t } = useTranslation();
const titleFieldId = useId();
const descriptionFieldId = useId();

return (
<Form noValidate>
<InputContainer>
<TitleLabel htmlFor="title-field" />
<TitleLabel htmlFor={titleFieldId} />
<Input
id="title-field"
id={titleFieldId}
value={event.title}
disabled
css={{ width: "100%" }}
/>
</InputContainer>

<InputContainer>
<label htmlFor="description-field">
<label htmlFor={descriptionFieldId}>
{t("upload.metadata.description")}
</label>
<TextArea id="description-field" disabled value={event.description ?? ""} />
<TextArea id={descriptionFieldId} disabled value={event.description ?? ""} />
</InputContainer>
</Form>
);
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/ui/SearchableSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ type SeriesSelectorProps = DerivedProps<SeriesOption> & {
onBlur?: () => void;
defaultValue?: SeriesOption;
writableOnly?: boolean;
inputId?: string;
};

type SeriesOption = {
Expand All @@ -130,7 +131,7 @@ type SeriesOption = {
};

export const SeriesSelector: React.FC<SeriesSelectorProps> = ({
writableOnly = false, onBlur, onChange, defaultValue, ...rest
writableOnly = false, onBlur, onChange, defaultValue, inputId, ...rest
}) => {
const { t } = useTranslation();
const [error, setError] = useState<ReactNode>(null);
Expand Down Expand Up @@ -174,6 +175,7 @@ export const SeriesSelector: React.FC<SeriesSelectorProps> = ({
format={formatSeriesOption}
onChange={onChange}
isDisabled={!!error}
{...{ inputId }}
{...{ onBlur, defaultValue }}
{...rest}
/>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ui/metadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { COLORS } from "../color";
export const TitleLabel: React.FC<{ htmlFor: string }> = ({ htmlFor }) => {
const { t } = useTranslation();
return (
<label htmlFor={htmlFor}>
<label {...{ htmlFor }}>
{t("upload.metadata.title")}
<FieldIsRequiredNote />
</label>
Expand Down

0 comments on commit ee465af

Please sign in to comment.