Merge pull request #17702 from overleaf/ii-bs5-to-bs3-classname-helper

[web] Bootstrap class name helper

GitOrigin-RevId: 9c2042aa2ea0e4d3828b32c321336e1c3a4a0ef8
This commit is contained in:
ilkin-overleaf 2024-04-03 14:01:56 +03:00 committed by Copybot
parent c22e6a5926
commit a9436039b6
7 changed files with 86 additions and 12 deletions

View file

@ -18,6 +18,7 @@ import { isValidEmail } from '../../../../shared/utils/email'
import getMeta from '../../../../utils/meta'
import { ReCaptcha2 } from '../../../../shared/components/recaptcha-2'
import { useRecaptcha } from '../../../../shared/hooks/use-recaptcha'
import { bsClassName } from '@/features/utils/bootstrap-5'
function AddEmail() {
const { t } = useTranslation()
@ -133,7 +134,10 @@ function AddEmail() {
const InputComponent = (
<>
<label htmlFor="affiliations-email" className="sr-only">
<label
htmlFor="affiliations-email"
className={bsClassName({ bs5: 'visually-hidden', bs3: 'sr-only' })}
>
{t('email')}
</label>
<Input
@ -157,7 +161,12 @@ function AddEmail() {
</Cell>
</Col>
<Col md={4}>
<Cell className="text-md-right">
<Cell
className={bsClassName({
bs5: 'text-md-end',
bs3: 'text-md-right',
})}
>
<AddNewEmailBtn email={newEmail} disabled />
</Cell>
</Col>
@ -197,7 +206,12 @@ function AddEmail() {
</Col>
{!isSsoAvailableForDomain ? (
<Col md={4}>
<Cell className="text-md-right">
<Cell
className={bsClassName({
bs5: 'text-md-end',
bs3: 'text-md-right',
})}
>
<AddNewEmailBtn
email={newEmail}
disabled={isLoading || state.isLoading}

View file

@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next'
import { useCombobox } from 'downshift'
import classnames from 'classnames'
import countries, { CountryCode } from '../../../data/countries-list'
import { bsClassName } from '@/features/utils/bootstrap-5'
type CountryInputProps = {
setValue: React.Dispatch<React.SetStateAction<CountryCode | null>>
@ -55,7 +56,10 @@ function Downshift({ setValue, inputRef }: CountryInputProps) {
>
<div {...getComboboxProps()} className="ui-select-toggle">
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label {...getLabelProps()} className="sr-only">
<label
{...getLabelProps()}
className={bsClassName({ bs5: 'visually-hidden', bs3: 'sr-only' })}
>
{t('country')}
</label>
<input

View file

@ -2,6 +2,7 @@ import { useState, useEffect, forwardRef } from 'react'
import { useCombobox } from 'downshift'
import classnames from 'classnames'
import { escapeRegExp } from 'lodash'
import { bsClassName } from '@/features/utils/bootstrap-5'
type DownshiftInputProps = {
highlightMatches?: boolean
@ -86,7 +87,14 @@ function Downshift({
>
<div {...getComboboxProps()}>
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label {...getLabelProps()} className={showLabel ? '' : 'sr-only'}>
<label
{...getLabelProps()}
className={
showLabel
? ''
: bsClassName({ bs5: 'visually-hidden', bs3: 'sr-only' })
}
>
{label}
</label>
<input

View file

@ -1,6 +1,8 @@
import { useTranslation } from 'react-i18next'
import { Row, Col } from 'react-bootstrap'
import EmailCell from './cell'
import classnames from 'classnames'
import { bsClassName } from '@/features/utils/bootstrap-5'
function Header() {
const { t } = useTranslation()
@ -8,19 +10,41 @@ function Header() {
return (
<>
<Row>
<Col md={4} className="hidden-xs">
<Col
md={4}
className={bsClassName({
bs5: 'd-none d-sm-block',
bs3: 'hidden-xs',
})}
>
<EmailCell>
<strong>{t('email')}</strong>
</EmailCell>
</Col>
<Col md={8} className="hidden-xs">
<Col
md={8}
className={bsClassName({
bs5: 'd-none d-sm-block',
bs3: 'hidden-xs',
})}
>
<EmailCell>
<strong>{t('institution_and_role')}</strong>
</EmailCell>
</Col>
</Row>
<div className="hidden-xs horizontal-divider" />
<div className="hidden-xs horizontal-divider" />
<div
className={classnames(
bsClassName({ bs5: 'd-none d-sm-block', bs3: 'hidden-xs' }),
'horizontal-divider'
)}
/>
<div
className={classnames(
bsClassName({ bs5: 'd-none d-sm-block', bs3: 'hidden-xs' }),
'horizontal-divider'
)}
/>
</>
)
}

View file

@ -13,6 +13,7 @@ import { ExposedSettings } from '../../../../../../types/exposed-settings'
import { ssoAvailableForInstitution } from '../../utils/sso'
import ReconfirmationInfo from './reconfirmation-info'
import { useLocation } from '../../../../shared/hooks/use-location'
import { bsClassName } from '@/features/utils/bootstrap-5'
type EmailsRowProps = {
userEmailData: UserEmailData
@ -40,7 +41,12 @@ function EmailsRow({ userEmailData }: EmailsRowProps) {
)}
</Col>
<Col md={3}>
<EmailCell className="text-md-right">
<EmailCell
className={bsClassName({
bs5: 'text-md-end',
bs3: 'text-md-right',
})}
>
<Actions userEmailData={userEmailData} />
</EmailCell>
</Col>
@ -144,7 +150,13 @@ function SSOAffiliationInfo({ userEmailData }: SSOAffiliationInfoProps) {
</p>
</EmailCell>
</Col>
<Col md={3} className="text-md-right">
<Col
md={3}
className={bsClassName({
bs5: 'text-md-end',
bs3: 'text-md-right',
})}
>
<EmailCell>
<Button
bsStyle="primary"

View file

@ -0,0 +1,7 @@
import getMeta from '@/utils/meta'
export const isBootstrap5 = getMeta('ol-bootstrapVersion') === 5
export const bsClassName = ({ bs5, bs3 }: { bs5: string; bs3: string }) => {
return isBootstrap5 ? bs5 : bs3
}

View file

@ -1,4 +1,5 @@
import classNames from 'classnames'
import { bsClassName } from '@/features/utils/bootstrap-5'
type IconOwnProps = {
type: string
@ -35,7 +36,11 @@ function Icon({
<>
<i className={iconClassName} aria-hidden="true" {...rest} />
{accessibilityLabel && (
<span className="sr-only">{accessibilityLabel}</span>
<span
className={bsClassName({ bs5: 'visually-hidden', bs3: 'sr-only' })}
>
{accessibilityLabel}
</span>
)}
</>
)