From 2f74b79d3a019fe70d8286846d04c2872c70a12d Mon Sep 17 00:00:00 2001 From: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:05:44 +0300 Subject: [PATCH] Merge pull request #17619 from overleaf/ii-bs5-rows-cols [web] Bootstrap 5 containers, rows, cols GitOrigin-RevId: 2b6b6fd1aebce739971e1428ab7c3cd6ec6c3858 --- .../settings/components/emails/add-email.tsx | 26 +++++----- .../components/emails/add-email/layout.tsx | 5 +- .../settings/components/emails/header.tsx | 15 +++--- .../components/emails/reconfirmation-info.tsx | 11 +++-- .../settings/components/emails/row.tsx | 48 ++++++++++--------- .../js/features/settings/components/root.tsx | 22 +++++---- .../bootstrap-version-switcher.tsx | 15 ++++++ .../bootstrap-5/wrappers/col-wrapper.tsx | 45 +++++++++++++++++ .../bootstrap-5/wrappers/row-wrapper.tsx | 16 +++++++ .../web/frontend/stories/ui/row.stories.tsx | 32 +++++++++++++ 10 files changed, 175 insertions(+), 60 deletions(-) create mode 100644 services/web/frontend/js/features/ui/components/bootstrap-5/bootstrap-version-switcher.tsx create mode 100644 services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/col-wrapper.tsx create mode 100644 services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/row-wrapper.tsx create mode 100644 services/web/frontend/stories/ui/row.stories.tsx diff --git a/services/web/frontend/js/features/settings/components/emails/add-email.tsx b/services/web/frontend/js/features/settings/components/emails/add-email.tsx index 3c8a2b8269..c26e2af865 100644 --- a/services/web/frontend/js/features/settings/components/emails/add-email.tsx +++ b/services/web/frontend/js/features/settings/components/emails/add-email.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react' import { useTranslation, Trans } from 'react-i18next' -import { Col } from 'react-bootstrap' import Cell from './cell' import Layout from './add-email/layout' import Input, { DomainInfo } from './add-email/input' @@ -18,6 +17,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 ColWrapper from '@/features/ui/components/bootstrap-5/wrappers/col-wrapper' import { bsClassName } from '@/features/utils/bootstrap-5' function AddEmail() { @@ -109,7 +109,7 @@ function AddEmail() { if (!isFormVisible) { return ( - + {state.data.emailCount >= emailAddressLimit ? ( @@ -127,7 +127,7 @@ function AddEmail() { )} - + ) } @@ -152,15 +152,15 @@ function AddEmail() {
- + {InputComponent}
{t('start_by_adding_your_email')}
- - +
+ - +
) @@ -182,7 +182,7 @@ function AddEmail() {
- + {InputComponent} {!isSsoAvailableForDomain ? ( @@ -203,9 +203,9 @@ function AddEmail() { ) : null} - + {!isSsoAvailableForDomain ? ( - + - + ) : ( - +
- +
)}
diff --git a/services/web/frontend/js/features/settings/components/emails/add-email/layout.tsx b/services/web/frontend/js/features/settings/components/emails/add-email/layout.tsx index 2ca36f0d19..045b61a775 100644 --- a/services/web/frontend/js/features/settings/components/emails/add-email/layout.tsx +++ b/services/web/frontend/js/features/settings/components/emails/add-email/layout.tsx @@ -1,7 +1,8 @@ -import { Row, Alert } from 'react-bootstrap' +import { Alert } from 'react-bootstrap' import Icon from '../../../../../shared/components/icon' import { UseAsyncReturnType } from '../../../../../shared/hooks/use-async' import { getUserFacingMessage } from '../../../../../infrastructure/fetch-json' +import RowWrapper from '@/features/ui/components/bootstrap-5/wrappers/row-wrapper' type LayoutProps = { children: React.ReactNode @@ -12,7 +13,7 @@ type LayoutProps = { function Layout({ isError, error, children }: LayoutProps) { return (
- {children} + {children} {isError && ( {getUserFacingMessage(error)} diff --git a/services/web/frontend/js/features/settings/components/emails/header.tsx b/services/web/frontend/js/features/settings/components/emails/header.tsx index 15a1c8fd6d..90622c42e8 100644 --- a/services/web/frontend/js/features/settings/components/emails/header.tsx +++ b/services/web/frontend/js/features/settings/components/emails/header.tsx @@ -1,6 +1,7 @@ import { useTranslation } from 'react-i18next' -import { Row, Col } from 'react-bootstrap' import EmailCell from './cell' +import ColWrapper from '@/features/ui/components/bootstrap-5/wrappers/col-wrapper' +import RowWrapper from '@/features/ui/components/bootstrap-5/wrappers/row-wrapper' import classnames from 'classnames' import { bsClassName } from '@/features/utils/bootstrap-5' @@ -9,8 +10,8 @@ function Header() { return ( <> - - + {t('email')} - - + {t('institution_and_role')} - - + +
- + +
{children}
- - +
+
) } diff --git a/services/web/frontend/js/features/settings/components/emails/row.tsx b/services/web/frontend/js/features/settings/components/emails/row.tsx index bcd5866ece..6d82a503a3 100644 --- a/services/web/frontend/js/features/settings/components/emails/row.tsx +++ b/services/web/frontend/js/features/settings/components/emails/row.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { Trans, useTranslation } from 'react-i18next' import { UserEmailData } from '../../../../../../types/user-email' -import { Button, Row, Col } from 'react-bootstrap' +import { Button } from 'react-bootstrap' import Email from './email' import InstitutionAndRole from './institution-and-role' import EmailCell from './cell' @@ -13,6 +13,8 @@ import { ExposedSettings } from '../../../../../../types/exposed-settings' import { ssoAvailableForInstitution } from '../../utils/sso' import ReconfirmationInfo from './reconfirmation-info' import { useLocation } from '../../../../shared/hooks/use-location' +import RowWrapper from '@/features/ui/components/bootstrap-5/wrappers/row-wrapper' +import ColWrapper from '@/features/ui/components/bootstrap-5/wrappers/col-wrapper' import { bsClassName } from '@/features/utils/bootstrap-5' type EmailsRowProps = { @@ -27,20 +29,20 @@ function EmailsRow({ userEmailData }: EmailsRowProps) { return ( <> - - + + - - + + {userEmailData.affiliation?.institution && ( )} - - + + - - + + {hasSSOAffiliation && ( @@ -91,8 +93,8 @@ function SSOAffiliationInfo({ userEmailData }: SSOAffiliationInfoProps) { if (userEmailData.samlProviderId) { return ( - - + +

- -
+ + ) } return ( - - + +
- - + +

- - + - -
- - + + + + ) } diff --git a/services/web/frontend/js/features/settings/components/root.tsx b/services/web/frontend/js/features/settings/components/root.tsx index 37d70594bc..0e5011d8cc 100644 --- a/services/web/frontend/js/features/settings/components/root.tsx +++ b/services/web/frontend/js/features/settings/components/root.tsx @@ -20,6 +20,8 @@ import useWaitForI18n from '../../../shared/hooks/use-wait-for-i18n' import useScrollToIdOnLoad from '../../../shared/hooks/use-scroll-to-id-on-load' import { ExposedSettings } from '../../../../../types/exposed-settings' import { SSOAlert } from './emails/sso-alert' +import RowWrapper from '@/features/ui/components/bootstrap-5/wrappers/row-wrapper' +import ColWrapper from '@/features/ui/components/bootstrap-5/wrappers/col-wrapper' function SettingsPageRoot() { const { isReady } = useWaitForI18n() @@ -31,11 +33,11 @@ function SettingsPageRoot() { return (
-
-
+ + {isReady ? : null} -
-
+ +
) } @@ -56,14 +58,14 @@ function SettingsPageContent() { -
-
+ + -
-
+ + -
-
+ +
diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/bootstrap-version-switcher.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/bootstrap-version-switcher.tsx new file mode 100644 index 0000000000..354444d67c --- /dev/null +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/bootstrap-version-switcher.tsx @@ -0,0 +1,15 @@ +import { isBootstrap5 } from '@/features/utils/bootstrap-5' + +type BootstrapVersionSwitcherProps = { + bs3: React.ReactNode + bs5: React.ReactNode +} + +function BootstrapVersionSwitcher({ + bs3, + bs5, +}: BootstrapVersionSwitcherProps): React.ReactElement { + return <>{isBootstrap5 ? bs5 : bs3} +} + +export default BootstrapVersionSwitcher diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/col-wrapper.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/col-wrapper.tsx new file mode 100644 index 0000000000..56066a76fd --- /dev/null +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/col-wrapper.tsx @@ -0,0 +1,45 @@ +import { Col } from 'react-bootstrap-5' +import { Col as BS3Col } from 'react-bootstrap' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' + +type ColWrapperProps = React.ComponentProps & { + bs3Props?: Record +} + +function ColWrapper(props: ColWrapperProps) { + const { bs3Props, ...rest } = props + const sizes = new Set(['xs', 'sm', 'md', 'lg', 'xl', 'xxl']) + + const getBs3Sizes = (obj: typeof rest) => { + return Object.entries(obj).reduce( + (prev, [key, value]) => { + if (sizes.has(key)) { + if (typeof value === 'object') { + prev[key] = value.span + prev[`${key}Offset`] = value.offset + } else { + prev[key] = value + } + } + return prev + }, + {} as Record + ) + } + + const bs3ColProps: React.ComponentProps = { + children: rest.children, + className: rest.className, + ...getBs3Sizes(rest), + ...bs3Props, + } + + return ( + } + bs5={} + /> + ) +} + +export default ColWrapper diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/row-wrapper.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/row-wrapper.tsx new file mode 100644 index 0000000000..fa5f09c77a --- /dev/null +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/wrappers/row-wrapper.tsx @@ -0,0 +1,16 @@ +import { Row } from 'react-bootstrap-5' +import { Row as BS3Row } from 'react-bootstrap' +import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' + +type RowWrapperProps = React.ComponentProps + +function RowWrapper(props: RowWrapperProps) { + return ( + {props.children}} + bs5={} + /> + ) +} + +export default RowWrapper diff --git a/services/web/frontend/stories/ui/row.stories.tsx b/services/web/frontend/stories/ui/row.stories.tsx new file mode 100644 index 0000000000..7dd24c4d9a --- /dev/null +++ b/services/web/frontend/stories/ui/row.stories.tsx @@ -0,0 +1,32 @@ +import { Container, Row, Col } from 'react-bootstrap-5' +import { Meta } from '@storybook/react' + +type Args = React.ComponentProps + +export const ColumnRowCell = (args: Args) => { + return ( + + + +
Col 1
+ + +
Col 2
+ + +
Col 3
+ +
+
+ ) +} + +const meta: Meta = { + title: 'Shared / Components / Bootstrap 5 / Column-Row-Cell', + component: Row, + parameters: { + bootstrap5: true, + }, +} + +export default meta