mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
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:
parent
c22e6a5926
commit
a9436039b6
7 changed files with 86 additions and 12 deletions
|
@ -18,6 +18,7 @@ import { isValidEmail } from '../../../../shared/utils/email'
|
||||||
import getMeta from '../../../../utils/meta'
|
import getMeta from '../../../../utils/meta'
|
||||||
import { ReCaptcha2 } from '../../../../shared/components/recaptcha-2'
|
import { ReCaptcha2 } from '../../../../shared/components/recaptcha-2'
|
||||||
import { useRecaptcha } from '../../../../shared/hooks/use-recaptcha'
|
import { useRecaptcha } from '../../../../shared/hooks/use-recaptcha'
|
||||||
|
import { bsClassName } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
function AddEmail() {
|
function AddEmail() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -133,7 +134,10 @@ function AddEmail() {
|
||||||
|
|
||||||
const InputComponent = (
|
const InputComponent = (
|
||||||
<>
|
<>
|
||||||
<label htmlFor="affiliations-email" className="sr-only">
|
<label
|
||||||
|
htmlFor="affiliations-email"
|
||||||
|
className={bsClassName({ bs5: 'visually-hidden', bs3: 'sr-only' })}
|
||||||
|
>
|
||||||
{t('email')}
|
{t('email')}
|
||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
|
@ -157,7 +161,12 @@ function AddEmail() {
|
||||||
</Cell>
|
</Cell>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={4}>
|
<Col md={4}>
|
||||||
<Cell className="text-md-right">
|
<Cell
|
||||||
|
className={bsClassName({
|
||||||
|
bs5: 'text-md-end',
|
||||||
|
bs3: 'text-md-right',
|
||||||
|
})}
|
||||||
|
>
|
||||||
<AddNewEmailBtn email={newEmail} disabled />
|
<AddNewEmailBtn email={newEmail} disabled />
|
||||||
</Cell>
|
</Cell>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -197,7 +206,12 @@ function AddEmail() {
|
||||||
</Col>
|
</Col>
|
||||||
{!isSsoAvailableForDomain ? (
|
{!isSsoAvailableForDomain ? (
|
||||||
<Col md={4}>
|
<Col md={4}>
|
||||||
<Cell className="text-md-right">
|
<Cell
|
||||||
|
className={bsClassName({
|
||||||
|
bs5: 'text-md-end',
|
||||||
|
bs3: 'text-md-right',
|
||||||
|
})}
|
||||||
|
>
|
||||||
<AddNewEmailBtn
|
<AddNewEmailBtn
|
||||||
email={newEmail}
|
email={newEmail}
|
||||||
disabled={isLoading || state.isLoading}
|
disabled={isLoading || state.isLoading}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next'
|
||||||
import { useCombobox } from 'downshift'
|
import { useCombobox } from 'downshift'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import countries, { CountryCode } from '../../../data/countries-list'
|
import countries, { CountryCode } from '../../../data/countries-list'
|
||||||
|
import { bsClassName } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
type CountryInputProps = {
|
type CountryInputProps = {
|
||||||
setValue: React.Dispatch<React.SetStateAction<CountryCode | null>>
|
setValue: React.Dispatch<React.SetStateAction<CountryCode | null>>
|
||||||
|
@ -55,7 +56,10 @@ function Downshift({ setValue, inputRef }: CountryInputProps) {
|
||||||
>
|
>
|
||||||
<div {...getComboboxProps()} className="ui-select-toggle">
|
<div {...getComboboxProps()} className="ui-select-toggle">
|
||||||
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
|
{/* 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')}
|
{t('country')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { useState, useEffect, forwardRef } from 'react'
|
||||||
import { useCombobox } from 'downshift'
|
import { useCombobox } from 'downshift'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { escapeRegExp } from 'lodash'
|
import { escapeRegExp } from 'lodash'
|
||||||
|
import { bsClassName } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
type DownshiftInputProps = {
|
type DownshiftInputProps = {
|
||||||
highlightMatches?: boolean
|
highlightMatches?: boolean
|
||||||
|
@ -86,7 +87,14 @@ function Downshift({
|
||||||
>
|
>
|
||||||
<div {...getComboboxProps()}>
|
<div {...getComboboxProps()}>
|
||||||
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
|
{/* 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}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Row, Col } from 'react-bootstrap'
|
import { Row, Col } from 'react-bootstrap'
|
||||||
import EmailCell from './cell'
|
import EmailCell from './cell'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
import { bsClassName } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
function Header() {
|
function Header() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -8,19 +10,41 @@ function Header() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={4} className="hidden-xs">
|
<Col
|
||||||
|
md={4}
|
||||||
|
className={bsClassName({
|
||||||
|
bs5: 'd-none d-sm-block',
|
||||||
|
bs3: 'hidden-xs',
|
||||||
|
})}
|
||||||
|
>
|
||||||
<EmailCell>
|
<EmailCell>
|
||||||
<strong>{t('email')}</strong>
|
<strong>{t('email')}</strong>
|
||||||
</EmailCell>
|
</EmailCell>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={8} className="hidden-xs">
|
<Col
|
||||||
|
md={8}
|
||||||
|
className={bsClassName({
|
||||||
|
bs5: 'd-none d-sm-block',
|
||||||
|
bs3: 'hidden-xs',
|
||||||
|
})}
|
||||||
|
>
|
||||||
<EmailCell>
|
<EmailCell>
|
||||||
<strong>{t('institution_and_role')}</strong>
|
<strong>{t('institution_and_role')}</strong>
|
||||||
</EmailCell>
|
</EmailCell>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<div className="hidden-xs horizontal-divider" />
|
<div
|
||||||
<div className="hidden-xs horizontal-divider" />
|
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'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { ExposedSettings } from '../../../../../../types/exposed-settings'
|
||||||
import { ssoAvailableForInstitution } from '../../utils/sso'
|
import { ssoAvailableForInstitution } from '../../utils/sso'
|
||||||
import ReconfirmationInfo from './reconfirmation-info'
|
import ReconfirmationInfo from './reconfirmation-info'
|
||||||
import { useLocation } from '../../../../shared/hooks/use-location'
|
import { useLocation } from '../../../../shared/hooks/use-location'
|
||||||
|
import { bsClassName } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
type EmailsRowProps = {
|
type EmailsRowProps = {
|
||||||
userEmailData: UserEmailData
|
userEmailData: UserEmailData
|
||||||
|
@ -40,7 +41,12 @@ function EmailsRow({ userEmailData }: EmailsRowProps) {
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={3}>
|
<Col md={3}>
|
||||||
<EmailCell className="text-md-right">
|
<EmailCell
|
||||||
|
className={bsClassName({
|
||||||
|
bs5: 'text-md-end',
|
||||||
|
bs3: 'text-md-right',
|
||||||
|
})}
|
||||||
|
>
|
||||||
<Actions userEmailData={userEmailData} />
|
<Actions userEmailData={userEmailData} />
|
||||||
</EmailCell>
|
</EmailCell>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -144,7 +150,13 @@ function SSOAffiliationInfo({ userEmailData }: SSOAffiliationInfoProps) {
|
||||||
</p>
|
</p>
|
||||||
</EmailCell>
|
</EmailCell>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={3} className="text-md-right">
|
<Col
|
||||||
|
md={3}
|
||||||
|
className={bsClassName({
|
||||||
|
bs5: 'text-md-end',
|
||||||
|
bs3: 'text-md-right',
|
||||||
|
})}
|
||||||
|
>
|
||||||
<EmailCell>
|
<EmailCell>
|
||||||
<Button
|
<Button
|
||||||
bsStyle="primary"
|
bsStyle="primary"
|
||||||
|
|
7
services/web/frontend/js/features/utils/bootstrap-5.ts
Normal file
7
services/web/frontend/js/features/utils/bootstrap-5.ts
Normal 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
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
import { bsClassName } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
type IconOwnProps = {
|
type IconOwnProps = {
|
||||||
type: string
|
type: string
|
||||||
|
@ -35,7 +36,11 @@ function Icon({
|
||||||
<>
|
<>
|
||||||
<i className={iconClassName} aria-hidden="true" {...rest} />
|
<i className={iconClassName} aria-hidden="true" {...rest} />
|
||||||
{accessibilityLabel && (
|
{accessibilityLabel && (
|
||||||
<span className="sr-only">{accessibilityLabel}</span>
|
<span
|
||||||
|
className={bsClassName({ bs5: 'visually-hidden', bs3: 'sr-only' })}
|
||||||
|
>
|
||||||
|
{accessibilityLabel}
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue