-
+
+
{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