From b45c24537db2c0618626ff15a5d76ee836697e72 Mon Sep 17 00:00:00 2001 From: Jay Sitter <jsit@users.noreply.github.com> Date: Tue, 4 Jul 2023 17:24:57 -0400 Subject: [PATCH] fix: Fix focus ring styles for radio button toggles #1772 (#1773) --- .../components/common/data-type-select.tsx | 54 ++++--- .../components/common/listing-type-select.tsx | 77 +++++---- src/shared/components/person/inbox.tsx | 147 +++++++++-------- src/shared/components/person/profile.tsx | 22 ++- .../person/registration-applications.tsx | 51 +++--- src/shared/components/person/reports.tsx | 148 ++++++++++-------- src/shared/components/post/post.tsx | 125 ++++++++------- 7 files changed, 363 insertions(+), 261 deletions(-) diff --git a/src/shared/components/common/data-type-select.tsx b/src/shared/components/common/data-type-select.tsx index 6bf0666..a0393f6 100644 --- a/src/shared/components/common/data-type-select.tsx +++ b/src/shared/components/common/data-type-select.tsx @@ -1,3 +1,5 @@ +import { randomStr } from "@utils/helpers"; +import classNames from "classnames"; import { Component, linkEvent } from "inferno"; import { DataType } from "../../interfaces"; import { I18NextService } from "../../services"; @@ -15,6 +17,8 @@ export class DataTypeSelect extends Component< DataTypeSelectProps, DataTypeSelectState > { + private id = `listing-type-input-${randomStr()}`; + state: DataTypeSelectState = { type_: this.props.type_, }; @@ -31,33 +35,41 @@ export class DataTypeSelect extends Component< render() { return ( - <div className="data-type-select btn-group btn-group-toggle flex-wrap"> + <div + className="data-type-select btn-group btn-group-toggle flex-wrap" + role="group" + > + <input + id={`${this.id}-posts`} + type="radio" + className="btn-check" + value={DataType.Post} + checked={this.state.type_ === DataType.Post} + onChange={linkEvent(this, this.handleTypeChange)} + /> <label - className={`pointer btn btn-outline-secondary - ${this.state.type_ == DataType.Post && "active"} - `} + htmlFor={`${this.id}-posts`} + className={classNames("pointer btn btn-outline-secondary", { + active: this.state.type_ === DataType.Post, + })} > - <input - type="radio" - className="btn-check" - value={DataType.Post} - checked={this.state.type_ == DataType.Post} - onChange={linkEvent(this, this.handleTypeChange)} - /> {I18NextService.i18n.t("posts")} </label> + + <input + id={`${this.id}-comments`} + type="radio" + className="btn-check" + value={DataType.Comment} + checked={this.state.type_ === DataType.Comment} + onChange={linkEvent(this, this.handleTypeChange)} + /> <label - className={`pointer btn btn-outline-secondary ${ - this.state.type_ == DataType.Comment && "active" - }`} + htmlFor={`${this.id}-comments`} + className={classNames("pointer btn btn-outline-secondary", { + active: this.state.type_ === DataType.Comment, + })} > - <input - type="radio" - className="btn-check" - value={DataType.Comment} - checked={this.state.type_ == DataType.Comment} - onChange={linkEvent(this, this.handleTypeChange)} - /> {I18NextService.i18n.t("comments")} </label> </div> diff --git a/src/shared/components/common/listing-type-select.tsx b/src/shared/components/common/listing-type-select.tsx index 9d0a1b9..1d917dc 100644 --- a/src/shared/components/common/listing-type-select.tsx +++ b/src/shared/components/common/listing-type-select.tsx @@ -1,4 +1,5 @@ import { randomStr } from "@utils/helpers"; +import classNames from "classnames"; import { Component, linkEvent } from "inferno"; import { ListingType } from "lemmy-js-client"; import { I18NextService, UserService } from "../../services"; @@ -38,60 +39,72 @@ export class ListingTypeSelect extends Component< render() { return ( - <div className="listing-type-select btn-group btn-group-toggle flex-wrap"> + <div + className="listing-type-select btn-group btn-group-toggle flex-wrap" + role="group" + > {this.props.showSubscribed && ( - <label - title={I18NextService.i18n.t("subscribed_description")} - className={`btn btn-outline-secondary - ${this.state.type_ == "Subscribed" && "active"} - ${!UserService.Instance.myUserInfo ? "disabled" : "pointer"} - `} - > + <> <input id={`${this.id}-subscribed`} type="radio" className="btn-check" value={"Subscribed"} - checked={this.state.type_ == "Subscribed"} + checked={this.state.type_ === "Subscribed"} onChange={linkEvent(this, this.handleTypeChange)} disabled={!UserService.Instance.myUserInfo} /> - {I18NextService.i18n.t("subscribed")} - </label> + <label + htmlFor={`${this.id}-subscribed`} + title={I18NextService.i18n.t("subscribed_description")} + className={classNames("btn btn-outline-secondary", { + active: this.state.type_ === "Subscribed", + disabled: !UserService.Instance.myUserInfo, + pointer: UserService.Instance.myUserInfo, + })} + > + {I18NextService.i18n.t("subscribed")} + </label> + </> )} {this.props.showLocal && ( - <label - title={I18NextService.i18n.t("local_description")} - className={`pointer btn btn-outline-secondary ${ - this.state.type_ == "Local" && "active" - }`} - > + <> <input id={`${this.id}-local`} type="radio" className="btn-check" value={"Local"} - checked={this.state.type_ == "Local"} + checked={this.state.type_ === "Local"} onChange={linkEvent(this, this.handleTypeChange)} /> - {I18NextService.i18n.t("local")} - </label> + <label + htmlFor={`${this.id}-local`} + title={I18NextService.i18n.t("local_description")} + className={classNames("pointer btn btn-outline-secondary", { + active: this.state.type_ === "Local", + })} + > + {I18NextService.i18n.t("local")} + </label> + </> )} + <input + id={`${this.id}-all`} + type="radio" + className="btn-check" + value={"All"} + checked={this.state.type_ === "All"} + onChange={linkEvent(this, this.handleTypeChange)} + /> <label title={I18NextService.i18n.t("all_description")} - className={`pointer btn btn-outline-secondary ${ - (this.state.type_ == "All" && "active") || - (!this.props.showLocal && this.state.type_ == "Local" && "active") - }`} + htmlFor={`${this.id}-all`} + className={classNames("pointer btn btn-outline-secondary", { + active: + this.state.type_ === "All" || + (!this.props.showLocal && this.state.type_) === "Local", + })} > - <input - id={`${this.id}-all`} - type="radio" - className="btn-check" - value={"All"} - checked={this.state.type_ == "All"} - onChange={linkEvent(this, this.handleTypeChange)} - /> {I18NextService.i18n.t("all")} </label> </div> diff --git a/src/shared/components/person/inbox.tsx b/src/shared/components/person/inbox.tsx index 28bb071..bf246f6 100644 --- a/src/shared/components/person/inbox.tsx +++ b/src/shared/components/person/inbox.tsx @@ -11,8 +11,9 @@ import { setIsoData, updatePersonBlock, } from "@utils/app"; -import { capitalizeFirstLetter } from "@utils/helpers"; +import { capitalizeFirstLetter, randomStr } from "@utils/helpers"; import { RouteDataResponse } from "@utils/types"; +import classNames from "classnames"; import { Component, linkEvent } from "inferno"; import { AddAdmin, @@ -283,34 +284,41 @@ export class Inbox extends Component<any, InboxState> { } unreadOrAllRadios() { + const radioId = randomStr(); + return ( - <div className="btn-group btn-group-toggle flex-wrap"> + <div className="btn-group btn-group-toggle flex-wrap" role="group"> + <input + id={`${radioId}-unread`} + type="radio" + className="btn-check" + value={UnreadOrAll.Unread} + checked={this.state.unreadOrAll === UnreadOrAll.Unread} + onChange={linkEvent(this, this.handleUnreadOrAllChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"} - `} + htmlFor={`${radioId}-unread`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.unreadOrAll === UnreadOrAll.Unread, + })} > - <input - type="radio" - className="btn-check" - value={UnreadOrAll.Unread} - checked={this.state.unreadOrAll == UnreadOrAll.Unread} - onChange={linkEvent(this, this.handleUnreadOrAllChange)} - /> {I18NextService.i18n.t("unread")} </label> + + <input + id={`${radioId}-all`} + type="radio" + className="btn-check" + value={UnreadOrAll.All} + checked={this.state.unreadOrAll === UnreadOrAll.All} + onChange={linkEvent(this, this.handleUnreadOrAllChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.unreadOrAll == UnreadOrAll.All && "active"} - `} + htmlFor={`${radioId}-all`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.unreadOrAll === UnreadOrAll.All, + })} > - <input - type="radio" - className="btn-check" - value={UnreadOrAll.All} - checked={this.state.unreadOrAll == UnreadOrAll.All} - onChange={linkEvent(this, this.handleUnreadOrAllChange)} - /> {I18NextService.i18n.t("all")} </label> </div> @@ -318,62 +326,75 @@ export class Inbox extends Component<any, InboxState> { } messageTypeRadios() { + const radioId = randomStr(); + return ( - <div className="btn-group btn-group-toggle flex-wrap"> + <div className="btn-group btn-group-toggle flex-wrap" role="group"> + <input + id={`${radioId}-all`} + type="radio" + className="btn-check" + value={MessageType.All} + checked={this.state.messageType === MessageType.All} + onChange={linkEvent(this, this.handleMessageTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.messageType == MessageType.All && "active"} - `} + htmlFor={`${radioId}-all`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.messageType === MessageType.All, + })} > - <input - type="radio" - className="btn-check" - value={MessageType.All} - checked={this.state.messageType == MessageType.All} - onChange={linkEvent(this, this.handleMessageTypeChange)} - /> {I18NextService.i18n.t("all")} </label> + + <input + id={`${radioId}-replies`} + type="radio" + className="btn-check" + value={MessageType.Replies} + checked={this.state.messageType === MessageType.Replies} + onChange={linkEvent(this, this.handleMessageTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.messageType == MessageType.Replies && "active"} - `} + htmlFor={`${radioId}-replies`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.messageType === MessageType.Replies, + })} > - <input - type="radio" - className="btn-check" - value={MessageType.Replies} - checked={this.state.messageType == MessageType.Replies} - onChange={linkEvent(this, this.handleMessageTypeChange)} - /> {I18NextService.i18n.t("replies")} </label> + + <input + id={`${radioId}-mentions`} + type="radio" + className="btn-check" + value={MessageType.Mentions} + checked={this.state.messageType === MessageType.Mentions} + onChange={linkEvent(this, this.handleMessageTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.messageType == MessageType.Mentions && "active"} - `} + htmlFor={`${radioId}-mentions`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.messageType === MessageType.Mentions, + })} > - <input - type="radio" - className="btn-check" - value={MessageType.Mentions} - checked={this.state.messageType == MessageType.Mentions} - onChange={linkEvent(this, this.handleMessageTypeChange)} - /> {I18NextService.i18n.t("mentions")} </label> + + <input + id={`${radioId}-messages`} + type="radio" + className="btn-check" + value={MessageType.Messages} + checked={this.state.messageType === MessageType.Messages} + onChange={linkEvent(this, this.handleMessageTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.messageType == MessageType.Messages && "active"} - `} + htmlFor={`${radioId}-messages`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.messageType === MessageType.Messages, + })} > - <input - type="radio" - className="btn-check" - value={MessageType.Messages} - checked={this.state.messageType == MessageType.Messages} - onChange={linkEvent(this, this.handleMessageTypeChange)} - /> {I18NextService.i18n.t("messages")} </label> </div> diff --git a/src/shared/components/person/profile.tsx b/src/shared/components/person/profile.tsx index 96ac3da..39979e2 100644 --- a/src/shared/components/person/profile.tsx +++ b/src/shared/components/person/profile.tsx @@ -18,6 +18,7 @@ import { getQueryParams, getQueryString, numToSI, + randomStr, } from "@utils/helpers"; import { canMod, isAdmin, isBanned } from "@utils/roles"; import type { QueryParams } from "@utils/types"; @@ -397,7 +398,7 @@ export class Profile extends Component< get viewRadios() { return ( - <div className="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2" role="group"> {this.getRadio(PersonDetailsView.Overview)} {this.getRadio(PersonDetailsView.Comments)} {this.getRadio(PersonDetailsView.Posts)} @@ -409,22 +410,27 @@ export class Profile extends Component< getRadio(view: PersonDetailsView) { const { view: urlView } = getProfileQueryParams(); const active = view === urlView; + const radioId = randomStr(); return ( - <label - className={classNames("btn btn-outline-secondary pointer", { - active, - })} - > + <> <input + id={radioId} type="radio" className="btn-check" value={view} checked={active} onChange={linkEvent(this, this.handleViewChange)} /> - {I18NextService.i18n.t(view.toLowerCase() as NoOptionI18nKeys)} - </label> + <label + htmlFor={radioId} + className={classNames("btn btn-outline-secondary pointer", { + active, + })} + > + {I18NextService.i18n.t(view.toLowerCase() as NoOptionI18nKeys)} + </label> + </> ); } diff --git a/src/shared/components/person/registration-applications.tsx b/src/shared/components/person/registration-applications.tsx index a26dd79..757170f 100644 --- a/src/shared/components/person/registration-applications.tsx +++ b/src/shared/components/person/registration-applications.tsx @@ -3,7 +3,9 @@ import { myAuthRequired, setIsoData, } from "@utils/app"; +import { randomStr } from "@utils/helpers"; import { RouteDataResponse } from "@utils/types"; +import classNames from "classnames"; import { Component, linkEvent } from "inferno"; import { ApproveRegistrationApplication, @@ -125,34 +127,41 @@ export class RegistrationApplications extends Component< } unreadOrAllRadios() { + const radioId = randomStr(); + return ( - <div className="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2" role="group"> + <input + id={`${radioId}-unread`} + type="radio" + className="btn-check" + value={UnreadOrAll.Unread} + checked={this.state.unreadOrAll === UnreadOrAll.Unread} + onChange={linkEvent(this, this.handleUnreadOrAllChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"} - `} + htmlFor={`${radioId}-unread`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.unreadOrAll === UnreadOrAll.Unread, + })} > - <input - type="radio" - className="btn-check" - value={UnreadOrAll.Unread} - checked={this.state.unreadOrAll == UnreadOrAll.Unread} - onChange={linkEvent(this, this.handleUnreadOrAllChange)} - /> {I18NextService.i18n.t("unread")} </label> + + <input + id={`${radioId}-all`} + type="radio" + className="btn-check" + value={UnreadOrAll.All} + checked={this.state.unreadOrAll === UnreadOrAll.All} + onChange={linkEvent(this, this.handleUnreadOrAllChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.unreadOrAll == UnreadOrAll.All && "active"} - `} + htmlFor={`${radioId}-all`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.unreadOrAll === UnreadOrAll.All, + })} > - <input - type="radio" - className="btn-check" - value={UnreadOrAll.All} - checked={this.state.unreadOrAll == UnreadOrAll.All} - onChange={linkEvent(this, this.handleUnreadOrAllChange)} - /> {I18NextService.i18n.t("all")} </label> </div> diff --git a/src/shared/components/person/reports.tsx b/src/shared/components/person/reports.tsx index c16b17a..d298930 100644 --- a/src/shared/components/person/reports.tsx +++ b/src/shared/components/person/reports.tsx @@ -5,8 +5,10 @@ import { myAuthRequired, setIsoData, } from "@utils/app"; +import { randomStr } from "@utils/helpers"; import { amAdmin } from "@utils/roles"; import { RouteDataResponse } from "@utils/types"; +import classNames from "classnames"; import { Component, linkEvent } from "inferno"; import { CommentReportResponse, @@ -187,34 +189,41 @@ export class Reports extends Component<any, ReportsState> { } unreadOrAllRadios() { + const radioId = randomStr(); + return ( - <div className="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2" role="group"> + <input + id={`${radioId}-unread`} + type="radio" + className="btn-check" + value={UnreadOrAll.Unread} + checked={this.state.unreadOrAll === UnreadOrAll.Unread} + onChange={linkEvent(this, this.handleUnreadOrAllChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"} - `} + htmlFor={`${radioId}-unread`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.unreadOrAll === UnreadOrAll.Unread, + })} > - <input - type="radio" - className="btn-check" - value={UnreadOrAll.Unread} - checked={this.state.unreadOrAll == UnreadOrAll.Unread} - onChange={linkEvent(this, this.handleUnreadOrAllChange)} - /> {I18NextService.i18n.t("unread")} </label> + + <input + id={`${radioId}-all`} + type="radio" + className="btn-check" + value={UnreadOrAll.All} + checked={this.state.unreadOrAll === UnreadOrAll.All} + onChange={linkEvent(this, this.handleUnreadOrAllChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.unreadOrAll == UnreadOrAll.All && "active"} - `} + htmlFor={`${radioId}-all`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.unreadOrAll === UnreadOrAll.All, + })} > - <input - type="radio" - className="btn-check" - value={UnreadOrAll.All} - checked={this.state.unreadOrAll == UnreadOrAll.All} - onChange={linkEvent(this, this.handleUnreadOrAllChange)} - /> {I18NextService.i18n.t("all")} </label> </div> @@ -222,70 +231,83 @@ export class Reports extends Component<any, ReportsState> { } messageTypeRadios() { + const radioId = randomStr(); + return ( - <div className="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2" role="group"> + <input + id={`${radioId}-all`} + type="radio" + className="btn-check" + value={MessageType.All} + checked={this.state.messageType === MessageType.All} + onChange={linkEvent(this, this.handleMessageTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.messageType == MessageType.All && "active"} - `} + htmlFor={`${radioId}-all`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.messageType === MessageType.All, + })} > - <input - type="radio" - className="btn-check" - value={MessageType.All} - checked={this.state.messageType == MessageType.All} - onChange={linkEvent(this, this.handleMessageTypeChange)} - /> {I18NextService.i18n.t("all")} </label> + + <input + id={`${radioId}-comments`} + type="radio" + className="btn-check" + value={MessageType.CommentReport} + checked={this.state.messageType === MessageType.CommentReport} + onChange={linkEvent(this, this.handleMessageTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.messageType == MessageType.CommentReport && "active"} - `} + htmlFor={`${radioId}-comments`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.messageType === MessageType.CommentReport, + })} > - <input - type="radio" - className="btn-check" - value={MessageType.CommentReport} - checked={this.state.messageType == MessageType.CommentReport} - onChange={linkEvent(this, this.handleMessageTypeChange)} - /> {I18NextService.i18n.t("comments")} </label> + + <input + id={`${radioId}-posts`} + type="radio" + className="btn-check" + value={MessageType.PostReport} + checked={this.state.messageType === MessageType.PostReport} + onChange={linkEvent(this, this.handleMessageTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer - ${this.state.messageType == MessageType.PostReport && "active"} - `} + htmlFor={`${radioId}-posts`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.messageType === MessageType.PostReport, + })} > - <input - type="radio" - className="btn-check" - value={MessageType.PostReport} - checked={this.state.messageType == MessageType.PostReport} - onChange={linkEvent(this, this.handleMessageTypeChange)} - /> {I18NextService.i18n.t("posts")} </label> + {amAdmin() && ( - <label - className={`btn btn-outline-secondary pointer - ${ - this.state.messageType == MessageType.PrivateMessageReport && - "active" - } - `} - > + <> <input + id={`${radioId}-messages`} type="radio" className="btn-check" value={MessageType.PrivateMessageReport} checked={ - this.state.messageType == MessageType.PrivateMessageReport + this.state.messageType === MessageType.PrivateMessageReport } onChange={linkEvent(this, this.handleMessageTypeChange)} /> - {I18NextService.i18n.t("messages")} - </label> + <label + htmlFor={`${radioId}-messages`} + className={classNames("btn btn-outline-secondary pointer", { + active: + this.state.messageType === MessageType.PrivateMessageReport, + })} + > + {I18NextService.i18n.t("messages")} + </label> + </> )} </div> ); diff --git a/src/shared/components/post/post.tsx b/src/shared/components/post/post.tsx index 3c0015e..f9d3512 100644 --- a/src/shared/components/post/post.tsx +++ b/src/shared/components/post/post.tsx @@ -19,10 +19,11 @@ import { restoreScrollPosition, saveScrollPosition, } from "@utils/browser"; -import { debounce } from "@utils/helpers"; +import { debounce, randomStr } from "@utils/helpers"; import { isImage } from "@utils/media"; import { RouteDataResponse } from "@utils/types"; import autosize from "autosize"; +import classNames from "classnames"; import { Component, RefObject, createRef, linkEvent } from "inferno"; import { AddAdmin, @@ -430,80 +431,98 @@ export class Post extends Component<any, PostState> { } sortRadios() { + const radioId = + this.state.postRes.state === "success" + ? this.state.postRes.data.post_view.post.id + : randomStr(); + return ( <> - <div className="btn-group btn-group-toggle flex-wrap me-3 mb-2"> + <div + className="btn-group btn-group-toggle flex-wrap me-3 mb-2" + role="group" + > + <input + id={`${radioId}-hot`} + type="radio" + className="btn-check" + value={"Hot"} + checked={this.state.commentSort === "Hot"} + onChange={linkEvent(this, this.handleCommentSortChange)} + /> <label - className={`btn btn-outline-secondary pointer ${ - this.state.commentSort === "Hot" && "active" - }`} + htmlFor={`${radioId}-hot`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.commentSort === "Hot", + })} > {I18NextService.i18n.t("hot")} - <input - type="radio" - className="btn-check" - value={"Hot"} - checked={this.state.commentSort === "Hot"} - onChange={linkEvent(this, this.handleCommentSortChange)} - /> </label> + <input + id={`${radioId}-top`} + type="radio" + className="btn-check" + value={"Top"} + checked={this.state.commentSort === "Top"} + onChange={linkEvent(this, this.handleCommentSortChange)} + /> <label - className={`btn btn-outline-secondary pointer ${ - this.state.commentSort === "Top" && "active" - }`} + htmlFor={`${radioId}-top`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.commentSort === "Top", + })} > {I18NextService.i18n.t("top")} - <input - type="radio" - className="btn-check" - value={"Top"} - checked={this.state.commentSort === "Top"} - onChange={linkEvent(this, this.handleCommentSortChange)} - /> </label> + <input + id={`${radioId}-new`} + type="radio" + className="btn-check" + value={"New"} + checked={this.state.commentSort === "New"} + onChange={linkEvent(this, this.handleCommentSortChange)} + /> <label - className={`btn btn-outline-secondary pointer ${ - this.state.commentSort === "New" && "active" - }`} + htmlFor={`${radioId}-new`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.commentSort === "New", + })} > {I18NextService.i18n.t("new")} - <input - type="radio" - className="btn-check" - value={"New"} - checked={this.state.commentSort === "New"} - onChange={linkEvent(this, this.handleCommentSortChange)} - /> </label> + <input + id={`${radioId}-old`} + type="radio" + className="btn-check" + value={"Old"} + checked={this.state.commentSort === "Old"} + onChange={linkEvent(this, this.handleCommentSortChange)} + /> <label - className={`btn btn-outline-secondary pointer ${ - this.state.commentSort === "Old" && "active" - }`} + htmlFor={`${radioId}-old`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.commentSort === "Old", + })} > {I18NextService.i18n.t("old")} - <input - type="radio" - className="btn-check" - value={"Old"} - checked={this.state.commentSort === "Old"} - onChange={linkEvent(this, this.handleCommentSortChange)} - /> </label> </div> - <div className="btn-group btn-group-toggle flex-wrap mb-2"> + <div className="btn-group btn-group-toggle flex-wrap mb-2" role="group"> + <input + id={`${radioId}-chat`} + type="radio" + className="btn-check" + value={CommentViewType.Flat} + checked={this.state.commentViewType === CommentViewType.Flat} + onChange={linkEvent(this, this.handleCommentViewTypeChange)} + /> <label - className={`btn btn-outline-secondary pointer ${ - this.state.commentViewType === CommentViewType.Flat && "active" - }`} + htmlFor={`${radioId}-chat`} + className={classNames("btn btn-outline-secondary pointer", { + active: this.state.commentViewType === CommentViewType.Flat, + })} > {I18NextService.i18n.t("chat")} - <input - type="radio" - className="btn-check" - value={CommentViewType.Flat} - checked={this.state.commentViewType === CommentViewType.Flat} - onChange={linkEvent(this, this.handleCommentViewTypeChange)} - /> </label> </div> </> -- 2.44.1