Remove Bootstrap 3 code from IDE page components (#23061)

GitOrigin-RevId: b41aff10672bf96e892de0be396a69eb25e2443b
This commit is contained in:
Alf Eaton
2025-03-06 10:54:40 +00:00
committed by Copybot
parent 07d9873ec9
commit a12e2001c3
228 changed files with 1253 additions and 3939 deletions
+4 -4
View File
@@ -126,8 +126,8 @@ const preview: Preview = {
// render stories in iframes, to isolate modals
inlineStories: false,
},
// Default to Bootstrap 3 styles
bootstrap5: false,
// Default to Bootstrap 5 styles
bootstrap5: true,
},
globalTypes: {
theme: {
@@ -166,10 +166,10 @@ const preview: Preview = {
const { bootstrap3Style, bootstrap5Style } = context.loaded
const bootstrapVersion = Number(
context.args[bootstrapVersionArg] ||
(context.parameters.bootstrap5 ? 5 : 3)
(context.parameters.bootstrap5 === false ? 3 : 5)
) as 3 | 5
const activeStyle =
bootstrapVersion === 5 ? bootstrap5Style : bootstrap3Style
bootstrapVersion === 3 ? bootstrap3Style : bootstrap5Style
resetMeta(bootstrapVersion)
@@ -10,11 +10,11 @@ export const bsVersionDecorator: Meta = {
control: { type: 'inline-radio' },
options: ['3', '5'],
table: {
defaultValue: { summary: '3' },
defaultValue: { summary: '5' },
},
},
},
args: {
[bootstrapVersionArg]: '3',
[bootstrapVersionArg]: '5',
},
}
@@ -5,6 +5,7 @@ import './shared/commands'
import './shared/exceptions'
import './ct/commands'
import './ct/codemirror'
import '../../test/frontend/helpers/bootstrap-5'
beforeEach(function () {
resetMeta()
@@ -10,6 +10,7 @@ export function resetMeta() {
hasLinkedProjectOutputFileFeature: true,
hasLinkUrlFeature: true,
})
window.metaAttributesCache.set('ol-bootstrapVersion', 5)
}
// Populate meta for top-level access in modules on import
@@ -84,11 +84,7 @@ export const waitForCompile = ({ prefix = 'compile', pdf = false } = {}) => {
}
export const interceptDeferredCompile = (beforeResponse?: () => void) => {
let resolveDeferredCompile: (value?: unknown) => void
const promise = new Promise(resolve => {
resolveDeferredCompile = resolve
})
const { promise, resolve } = Promise.withResolvers<void>()
cy.intercept(
{ method: 'POST', url: '/project/*/compile*', times: 1 },
@@ -148,6 +144,5 @@ export const interceptDeferredCompile = (beforeResponse?: () => void) => {
{ fixture: 'build/output.blg' }
).as(`compile-blg`)
// @ts-ignore
return cy.wrap(resolveDeferredCompile)
return cy.wrap(resolve)
}
@@ -342,7 +342,6 @@
"create_project_in_github": "",
"created": "",
"created_at": "",
"creating": "",
"current_file": "",
"current_password": "",
"currently_seeing_only_24_hrs_history": "",
@@ -699,12 +698,10 @@
"hide_outline": "",
"history": "",
"history_add_label": "",
"history_adding_label": "",
"history_are_you_sure_delete_label": "",
"history_compare_from_this_version": "",
"history_compare_up_to_this_version": "",
"history_delete_label": "",
"history_deleting_label": "",
"history_download_this_version": "",
"history_entry_origin_dropbox": "",
"history_entry_origin_git": "",
@@ -1384,7 +1381,6 @@
"restore_file_version": "",
"restore_project_to_this_version": "",
"restore_this_version": "",
"restoring": "",
"resync_completed": "",
"resync_message": "",
"resync_project_history": "",
@@ -4,22 +4,17 @@ import { useTranslation } from 'react-i18next'
import MessageInput from './message-input'
import InfiniteScroll from './infinite-scroll'
import ChatFallbackError from './chat-fallback-error'
import Icon from '../../../shared/components/icon'
import { useLayoutContext } from '../../../shared/context/layout-context'
import { useUserContext } from '../../../shared/context/user-context'
import withErrorBoundary from '../../../infrastructure/error-boundary'
import { FetchError } from '../../../infrastructure/fetch-json'
import { useChatContext } from '../context/chat-context'
import { FullSizeLoadingSpinner } from '../../../shared/components/loading-spinner'
import { bsVersion } from '@/features/utils/bootstrap-5'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
const MessageList = lazy(() => import('./message-list'))
const Loading = () => (
<FullSizeLoadingSpinner delay={500} className={bsVersion({ bs5: 'pt-4' })} />
)
const Loading = () => <FullSizeLoadingSpinner delay={500} className="pt-4" />
const ChatPane = React.memo(function ChatPane() {
const { t } = useTranslation()
@@ -86,9 +81,7 @@ const ChatPane = React.memo(function ChatPane() {
itemCount={messageContentCount}
>
<div>
<h2 className={bsVersion({ bs3: 'sr-only', bs5: 'visually-hidden' })}>
{t('chat')}
</h2>
<h2 className="visually-hidden">{t('chat')}</h2>
<Suspense fallback={<Loading />}>
{status === 'pending' && <Loading />}
{shouldDisplayPlaceholder && <Placeholder />}
@@ -115,10 +108,7 @@ function Placeholder() {
<div className="first-message text-center">
{t('send_first_message')}
<br />
<BootstrapVersionSwitcher
bs3={<Icon type="arrow-down" />}
bs5={<MaterialIcon type="arrow_downward" />}
/>
<MaterialIcon type="arrow_downward" />
</div>
</>
)
@@ -1,5 +1,4 @@
import { useTranslation } from 'react-i18next'
import { bsVersion } from '@/features/utils/bootstrap-5'
type MessageInputProps = {
resetUnreadMessages: () => void
@@ -27,10 +26,7 @@ function MessageInput({ resetUnreadMessages, sendMessage }: MessageInputProps) {
return (
<form className="new-message">
<label
htmlFor="chat-input"
className={bsVersion({ bs3: 'sr-only', bs5: 'visually-hidden' })}
>
<label htmlFor="chat-input" className="visually-hidden">
{t('your_message_to_collaborators')}
</label>
<textarea
@@ -1,53 +1,26 @@
import { FC } from 'react'
import { Tag as TagType } from '../../../../../app/src/Features/Tags/types'
import { getTagColor } from '@/features/project-list/util/tag'
import Icon from '@/shared/components/icon'
import { useTranslation } from 'react-i18next'
import Tag from '@/features/ui/components/bootstrap-5/tag'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
export const CloneProjectTag: FC<{
tag: TagType
removeTag: (tag: TagType) => void
}> = ({ tag, removeTag }) => {
const { t } = useTranslation()
return (
<BootstrapVersionSwitcher
bs3={
<div className="tag-label" role="option" aria-selected>
<span className="label label-default tag-label-name">
<span style={{ color: getTagColor(tag) }}>
<Icon type="circle" aria-hidden />
</span>{' '}
{tag.name}
</span>
<button
type="button"
className="label label-default tag-label-remove"
onClick={() => removeTag(tag)}
aria-label={t('remove_tag', { tagName: tag.name })}
>
<span aria-hidden="true">×</span>
</button>
</div>
<Tag
prepend={
<i
className="badge-tag-circle"
style={{ backgroundColor: getTagColor(tag) }}
/>
}
bs5={
<Tag
prepend={
<i
className="badge-tag-circle"
style={{ backgroundColor: getTagColor(tag) }}
/>
}
closeBtnProps={{
onClick: () => removeTag(tag),
}}
className="ms-2 mb-2"
>
{tag.name}
</Tag>
}
/>
closeBtnProps={{
onClick: () => removeTag(tag),
}}
className="ms-2 mb-2"
>
{tag.name}
</Tag>
)
}
@@ -13,7 +13,6 @@ import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import OLNotification from '@/features/ui/components/ol/ol-notification'
import OLButton from '@/features/ui/components/ol/ol-button'
import OLIconButton from '@/features/ui/components/ol/ol-icon-button'
import { bsVersion } from '@/features/utils/bootstrap-5'
import { learnedWords as initialLearnedWords } from '@/features/source-editor/extensions/spelling/learned-words'
type DictionaryModalContentProps = {
@@ -79,13 +78,7 @@ export default function DictionaryModalContent({
variant="danger"
size="sm"
onClick={() => handleRemove(learnedWord)}
bs3Props={{ bsSize: 'xsmall' }}
icon={
bsVersion({
bs5: 'delete',
bs3: 'trash-o',
}) as string
}
icon="delete"
accessibilityLabel={t('edit_dictionary_remove')}
/>
</OLTooltip>
@@ -1,10 +1,8 @@
import { useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import { useProjectContext } from '../../../shared/context/project-context'
import Icon from '../../../shared/components/icon'
import * as eventTracking from '../../../infrastructure/event-tracking'
import { isSmallDevice } from '../../../infrastructure/event-tracking'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
@@ -29,10 +27,7 @@ export default function DownloadPDF() {
rel="noreferrer"
onClick={sendDownloadEvent}
>
<BootstrapVersionSwitcher
bs3={<Icon type="file-pdf-o" modifier="2x" />}
bs5={<MaterialIcon type="picture_as_pdf" size="2x" />}
/>
<MaterialIcon type="picture_as_pdf" size="2x" />
<br />
PDF
</a>
@@ -45,10 +40,7 @@ export default function DownloadPDF() {
overlayProps={{ placement: 'bottom' }}
>
<div className="link-disabled">
<BootstrapVersionSwitcher
bs3={<Icon type="file-pdf-o" modifier="2x" />}
bs5={<MaterialIcon type="picture_as_pdf" size="2x" />}
/>
<MaterialIcon type="picture_as_pdf" size="2x" />
<br />
PDF
</div>
@@ -1,9 +1,7 @@
import { useTranslation } from 'react-i18next'
import { useProjectContext } from '../../../shared/context/project-context'
import Icon from '../../../shared/components/icon'
import * as eventTracking from '../../../infrastructure/event-tracking'
import { isSmallDevice } from '../../../infrastructure/event-tracking'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export default function DownloadSource() {
@@ -25,10 +23,7 @@ export default function DownloadSource() {
rel="noreferrer"
onClick={sendDownloadEvent}
>
<BootstrapVersionSwitcher
bs3={<Icon type="file-archive-o" modifier="2x" />}
bs5={<MaterialIcon type="folder_zip" size="2x" />}
/>
<MaterialIcon type="folder_zip" size="2x" />
<br />
{t('source')}
</a>
@@ -1,11 +1,8 @@
import { useLayoutContext } from '../../../shared/context/layout-context'
import LeftMenuMask from './left-menu-mask'
import AccessibleModal from '../../../shared/components/accessible-modal'
import { Modal } from 'react-bootstrap'
import classNames from 'classnames'
import { lazy, memo, Suspense } from 'react'
import { FullSizeLoadingSpinner } from '@/shared/components/loading-spinner'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { Offcanvas } from 'react-bootstrap-5'
import { EditorLeftMenuProvider } from './editor-left-menu-context'
import withErrorBoundary from '@/infrastructure/error-boundary'
@@ -34,49 +31,24 @@ function EditorLeftMenu() {
}
return (
<BootstrapVersionSwitcher
bs3={
<EditorLeftMenuProvider>
<AccessibleModal
backdropClassName="left-menu-modal-backdrop"
keyboard
onHide={closeLeftMenu}
id="left-menu-modal"
show={leftMenuShown}
>
<Modal.Body
className={classNames('full-size', { shown: leftMenuShown })}
id="left-menu"
>
<Suspense fallback={<FullSizeLoadingSpinner delay={500} />}>
<EditorLeftMenuBody />
</Suspense>
</Modal.Body>
</AccessibleModal>
{leftMenuShown && <LeftMenuMask />}
</EditorLeftMenuProvider>
}
bs5={
<EditorLeftMenuProvider>
<Offcanvas
show={leftMenuShown}
onHide={closeLeftMenu}
backdropClassName="left-menu-modal-backdrop"
id="left-menu-offcanvas"
>
<Offcanvas.Body
className={classNames('full-size', 'left-menu', {
shown: leftMenuShown,
})}
id="left-menu"
>
<LazyEditorLeftMenuWithErrorBoundary />
</Offcanvas.Body>
</Offcanvas>
{leftMenuShown && <LeftMenuMask />}
</EditorLeftMenuProvider>
}
/>
<EditorLeftMenuProvider>
<Offcanvas
show={leftMenuShown}
onHide={closeLeftMenu}
backdropClassName="left-menu-modal-backdrop"
id="left-menu-offcanvas"
>
<Offcanvas.Body
className={classNames('full-size', 'left-menu', {
shown: leftMenuShown,
})}
id="left-menu"
>
<LazyEditorLeftMenuWithErrorBoundary />
</Offcanvas.Body>
</Offcanvas>
{leftMenuShown && <LeftMenuMask />}
</EditorLeftMenuProvider>
)
}
@@ -1,6 +1,4 @@
import { PropsWithChildren } from 'react'
import Icon from '../../../shared/components/icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
type Props = {
@@ -26,12 +24,7 @@ function LeftMenuButtonIcon({
if (svgIcon) {
return <div className="material-symbols">{svgIcon}</div>
} else if (icon) {
return (
<BootstrapVersionSwitcher
bs3={<Icon type={icon.type} fw={icon.fw ?? false} />}
bs5={<MaterialIcon type={icon.type} />}
/>
)
return <MaterialIcon type={icon.type} />
} else return null
}
@@ -17,7 +17,6 @@ export default function SettingsDictionary() {
variant="secondary"
size="sm"
onClick={() => setShowModal(true)}
bs3Props={{ bsSize: 'xsmall' }}
>
{t('edit')}
</OLButton>
@@ -1,4 +1,3 @@
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
import OLFormLabel from '@/features/ui/components/ol/ol-form-label'
import OLFormSelect from '@/features/ui/components/ol/ol-form-select'
@@ -81,23 +80,14 @@ export default function SettingsMenuSelect<T extends PossibleValue = string>({
>
<OLFormLabel>{label}</OLFormLabel>
{loading ? (
<BootstrapVersionSwitcher
bs3={
<p className="loading pull-right">
<i className="fa fa-fw fa-spin fa-refresh" />
</p>
}
bs5={
<p className="mb-0">
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
</p>
}
/>
<p className="mb-0">
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
</p>
) : (
<OLFormSelect
size="sm"
@@ -1,8 +1,6 @@
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import * as eventTracking from '../../../infrastructure/event-tracking'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
function BackToProjectsButton() {
@@ -23,21 +21,10 @@ function BackToProjectsButton() {
eventTracking.sendMB('navigation-clicked-home')
}}
>
<BootstrapVersionSwitcher
bs3={
<Icon
type="home"
fw
accessibilityLabel={t('back_to_your_projects')}
/>
}
bs5={
<MaterialIcon
type="home"
className="align-text-bottom"
accessibilityLabel={t('back_to_your_projects')}
/>
}
<MaterialIcon
type="home"
className="align-text-bottom"
accessibilityLabel={t('back_to_your_projects')}
/>
</a>
</div>
@@ -1,8 +1,6 @@
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import OLBadge from '@/features/ui/components/ol/ol-badge'
@@ -15,22 +13,11 @@ function ChatToggleButton({ chatIsOpen, unreadMessageCount, onClick }) {
return (
<div className="toolbar-item">
<button type="button" className={classes} onClick={onClick}>
<BootstrapVersionSwitcher
bs3={
<Icon
type="comment"
fw
className={classNames({ bounce: hasUnreadMessages })}
/>
}
bs5={
<MaterialIcon
type="chat"
className={classNames('align-middle', {
bounce: hasUnreadMessages,
})}
/>
}
<MaterialIcon
type="chat"
className={classNames('align-middle', {
bounce: hasUnreadMessages,
})}
/>
{hasUnreadMessages && <OLBadge bg="info">{unreadMessageCount}</OLBadge>}
<p className="toolbar-label">{t('chat')}</p>
@@ -1,8 +1,6 @@
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function HistoryToggleButton({ onClick }) {
const { t } = useTranslation()
@@ -10,10 +8,7 @@ function HistoryToggleButton({ onClick }) {
return (
<div className="toolbar-item">
<button type="button" className="btn btn-full-height" onClick={onClick}>
<BootstrapVersionSwitcher
bs3={<Icon type="history" fw />}
bs5={<MaterialIcon type="history" className="align-middle" />}
/>
<MaterialIcon type="history" className="align-middle" />
<p className="toolbar-label">{t('history')}</p>
</button>
</div>
@@ -1,9 +1,4 @@
import { memo, ReactNode, useCallback, forwardRef } from 'react'
import {
Dropdown as BS3Dropdown,
MenuItem,
MenuItemProps,
} from 'react-bootstrap'
import { memo, useCallback, forwardRef } from 'react'
import { Spinner } from 'react-bootstrap-5'
import {
Dropdown,
@@ -13,10 +8,6 @@ import {
DropdownToggleCustom,
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import { Trans, useTranslation } from 'react-i18next'
import Tooltip from '../../../shared/components/tooltip'
import Icon from '../../../shared/components/icon'
import IconChecked from '../../../shared/components/icon-checked'
import ControlledDropdown from '../../../shared/components/controlled-dropdown'
import {
IdeLayout,
IdeView,
@@ -25,38 +16,9 @@ import {
import * as eventTracking from '../../../infrastructure/event-tracking'
import useEventListener from '../../../shared/hooks/use-event-listener'
import { DetachRole } from '@/shared/context/detach-context'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
function IconPlaceholder() {
return <Icon type="" fw />
}
function IconRefresh() {
return <Icon type="refresh" fw spin />
}
function IconLayout() {
return <Icon type="columns" fw />
}
function IconSplit() {
return <Icon type="columns" fw />
}
function IconDetach() {
return <Icon type="window-restore" fw />
}
function IconEditorOnly() {
return <Icon type="code" fw />
}
function IconPdfOnly() {
return <Icon type="file-pdf-o" fw />
}
const isActiveDropdownItem = ({
iconFor,
pdfLayout,
@@ -85,33 +47,6 @@ const isActiveDropdownItem = ({
return false
}
function IconCheckmark(props: Parameters<typeof isActiveDropdownItem>[0]) {
return isActiveDropdownItem(props) ? <IconChecked /> : <IconPlaceholder />
}
function LayoutMenuItem({
checkmark,
icon,
text,
...props
}: {
checkmark: ReactNode
icon: ReactNode
text: string | ReactNode
} & MenuItemProps) {
return (
<MenuItem {...props}>
<div className="layout-menu-item">
<div className="layout-menu-item-start">
<div>{checkmark}</div>
<div>{icon}</div>
<div>{text}</div>
</div>
</div>
</MenuItem>
)
}
function EnhancedDropdownItem({
active,
...props
@@ -141,25 +76,6 @@ const LayoutDropdownToggleButton = forwardRef<
})
LayoutDropdownToggleButton.displayName = 'LayoutDropdownToggleButton'
function BS3DetachDisabled() {
const { t } = useTranslation()
return (
<Tooltip
id="detach-disabled"
description={t('your_browser_does_not_support_this_feature')}
overlayProps={{ placement: 'left' }}
>
<LayoutMenuItem
disabled
checkmark={<IconPlaceholder />}
icon={<IconDetach />}
text={t('pdf_in_separate_tab')}
/>
</Tooltip>
)
}
function BS5DetachDisabled() {
const { t } = useTranslation()
@@ -260,208 +176,108 @@ export const LayoutDropdownButtonUi = ({
{t('layout_processing')}
</div>
)}
<BootstrapVersionSwitcher
bs3={
<ControlledDropdown
id="layout-dropdown"
onMainButtonClick={() => {
eventTracking.sendMB('navigation-clicked-layout')
}}
className="toolbar-item layout-dropdown"
pullRight
<Dropdown className="toolbar-item layout-dropdown" align="end">
<DropdownToggle
id="layout-dropdown-btn"
className="btn-full-height"
as={LayoutDropdownToggleButton}
>
{processing ? (
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
) : (
<MaterialIcon type="dock_to_right" className="align-middle" />
)}
<span className="toolbar-label">{t('layout')}</span>
</DropdownToggle>
<DropdownMenu>
<EnhancedDropdownItem
onClick={() => handleChangeLayout('sideBySide')}
active={isActiveDropdownItem({
iconFor: 'sideBySide',
pdfLayout,
view,
detachRole,
})}
leadingIcon="dock_to_right"
>
{/* bsStyle is required for Dropdown.Toggle, but we will override style */}
<BS3Dropdown.Toggle className="btn-full-height" bsStyle="link">
{processing ? <IconRefresh /> : <IconLayout />}
<span className="toolbar-label">{t('layout')}</span>
</BS3Dropdown.Toggle>
<BS3Dropdown.Menu className="layout-dropdown-list">
<LayoutMenuItem
onSelect={() => handleChangeLayout('sideBySide')}
checkmark={
<IconCheckmark
iconFor="sideBySide"
pdfLayout={pdfLayout}
view={view}
detachRole={detachRole}
/>
}
icon={<IconSplit />}
text={t('editor_and_pdf')}
/>
{t('editor_and_pdf')}
</EnhancedDropdownItem>
<LayoutMenuItem
onSelect={() => handleChangeLayout('flat', 'editor')}
checkmark={
<IconCheckmark
iconFor="editorOnly"
pdfLayout={pdfLayout}
view={view}
detachRole={detachRole}
/>
}
icon={<IconEditorOnly />}
text={
<Trans
i18nKey="editor_only_hide_pdf"
components={[
<span key="editor_only_hide_pdf" className="subdued" />,
]}
/>
}
<EnhancedDropdownItem
onClick={() => handleChangeLayout('flat', 'editor')}
active={isActiveDropdownItem({
iconFor: 'editorOnly',
pdfLayout,
view,
detachRole,
})}
leadingIcon="code"
>
<div className="d-flex flex-column">
<Trans
i18nKey="editor_only_hide_pdf"
components={[
<span key="editor_only_hide_pdf" className="subdued" />,
]}
/>
</div>
</EnhancedDropdownItem>
<LayoutMenuItem
onSelect={() => handleChangeLayout('flat', 'pdf')}
checkmark={
<IconCheckmark
iconFor="pdfOnly"
pdfLayout={pdfLayout}
view={view}
detachRole={detachRole}
/>
}
icon={<IconPdfOnly />}
text={
<Trans
i18nKey="pdf_only_hide_editor"
components={[
<span key="pdf_only_hide_editor" className="subdued" />,
]}
/>
}
<EnhancedDropdownItem
onClick={() => handleChangeLayout('flat', 'pdf')}
active={isActiveDropdownItem({
iconFor: 'pdfOnly',
pdfLayout,
view,
detachRole,
})}
leadingIcon="picture_as_pdf"
>
<div className="d-flex flex-column">
<Trans
i18nKey="pdf_only_hide_editor"
components={[
<span key="pdf_only_hide_editor" className="subdued" />,
]}
/>
</div>
</EnhancedDropdownItem>
{detachable ? (
<LayoutMenuItem
onSelect={() => handleDetach()}
checkmark={
detachRole === 'detacher' ? (
detachIsLinked ? (
<IconChecked />
) : (
<IconRefresh />
)
) : (
<IconPlaceholder />
)
}
icon={<IconDetach />}
text={t('pdf_in_separate_tab')}
/>
) : (
<BS3DetachDisabled />
)}
</BS3Dropdown.Menu>
</ControlledDropdown>
}
bs5={
<Dropdown className="toolbar-item layout-dropdown" align="end">
<DropdownToggle
id="layout-dropdown-btn"
className="btn-full-height"
as={LayoutDropdownToggleButton}
{detachable ? (
<EnhancedDropdownItem
onClick={() => handleDetach()}
active={detachRole === 'detacher' && detachIsLinked}
trailingIcon={
detachRole === 'detacher' ? (
detachIsLinked ? (
'check'
) : (
<span className="spinner-container">
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
<span className="visually-hidden">{t('loading')}</span>
</span>
)
) : null
}
leadingIcon="select_window"
>
{processing ? (
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
) : (
<MaterialIcon type="dock_to_right" className="align-middle" />
)}
<span className="toolbar-label">{t('layout')}</span>
</DropdownToggle>
<DropdownMenu>
<EnhancedDropdownItem
onClick={() => handleChangeLayout('sideBySide')}
active={isActiveDropdownItem({
iconFor: 'sideBySide',
pdfLayout,
view,
detachRole,
})}
leadingIcon="dock_to_right"
>
{t('editor_and_pdf')}
</EnhancedDropdownItem>
<EnhancedDropdownItem
onClick={() => handleChangeLayout('flat', 'editor')}
active={isActiveDropdownItem({
iconFor: 'editorOnly',
pdfLayout,
view,
detachRole,
})}
leadingIcon="code"
>
<div className="d-flex flex-column">
<Trans
i18nKey="editor_only_hide_pdf"
components={[
<span key="editor_only_hide_pdf" className="subdued" />,
]}
/>
</div>
</EnhancedDropdownItem>
<EnhancedDropdownItem
onClick={() => handleChangeLayout('flat', 'pdf')}
active={isActiveDropdownItem({
iconFor: 'pdfOnly',
pdfLayout,
view,
detachRole,
})}
leadingIcon="picture_as_pdf"
>
<div className="d-flex flex-column">
<Trans
i18nKey="pdf_only_hide_editor"
components={[
<span key="pdf_only_hide_editor" className="subdued" />,
]}
/>
</div>
</EnhancedDropdownItem>
{detachable ? (
<EnhancedDropdownItem
onClick={() => handleDetach()}
active={detachRole === 'detacher' && detachIsLinked}
trailingIcon={
detachRole === 'detacher' ? (
detachIsLinked ? (
'check'
) : (
<span className="spinner-container">
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
<span className="visually-hidden">
{t('loading')}
</span>
</span>
)
) : null
}
leadingIcon="select_window"
>
{t('pdf_in_separate_tab')}
</EnhancedDropdownItem>
) : (
<BS5DetachDisabled />
)}
</DropdownMenu>
</Dropdown>
}
/>
{t('pdf_in_separate_tab')}
</EnhancedDropdownItem>
) : (
<BS5DetachDisabled />
)}
</DropdownMenu>
</Dropdown>
</>
)
}
@@ -1,8 +1,6 @@
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function MenuButton({ onClick }) {
const { t } = useTranslation()
@@ -10,15 +8,7 @@ function MenuButton({ onClick }) {
return (
<div className="toolbar-item">
<button type="button" className="btn btn-full-height" onClick={onClick}>
<BootstrapVersionSwitcher
bs3={<Icon type="bars" fw className="editor-menu-icon" />}
bs5={
<MaterialIcon
type="menu"
className="editor-menu-icon align-middle"
/>
}
/>
<MaterialIcon type="menu" className="editor-menu-icon align-middle" />
<p className="toolbar-label">{t('menu')}</p>
</button>
</div>
@@ -1,7 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import { Dropdown as BS3Dropdown, MenuItem } from 'react-bootstrap'
import {
Dropdown,
DropdownHeader,
@@ -9,11 +8,8 @@ import {
DropdownMenu,
DropdownToggle,
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import Icon from '../../../shared/components/icon'
import { getBackgroundColorForUserId } from '@/shared/utils/colors'
import ControlledDropdown from '../../../shared/components/controlled-dropdown'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
function OnlineUsersWidget({ onlineUsers, goToUser }) {
@@ -23,57 +19,28 @@ function OnlineUsersWidget({ onlineUsers, goToUser }) {
if (shouldDisplayDropdown) {
return (
<BootstrapVersionSwitcher
bs3={
<ControlledDropdown
id="online-users"
className="online-users"
pullRight
>
<DropDownToggleButton
bsRole="toggle"
onlineUserCount={onlineUsers.length}
/>
<BS3Dropdown.Menu>
<MenuItem header>{t('connected_users')}</MenuItem>
{onlineUsers.map((user, index) => (
<MenuItem
as="button"
key={`${user.user_id}_${index}`}
eventKey={user}
onSelect={goToUser}
>
<UserIcon user={user} showName />
</MenuItem>
))}
</BS3Dropdown.Menu>
</ControlledDropdown>
}
bs5={
<Dropdown id="online-users" className="online-users" align="end">
<DropdownToggle
as={DropDownToggleButton}
onlineUserCount={onlineUsers.length}
/>
<DropdownMenu>
<DropdownHeader aria-hidden="true">
{t('connected_users')}
</DropdownHeader>
{onlineUsers.map((user, index) => (
<li role="none" key={`${user.user_id}_${index}`}>
<DropdownItem
as="button"
tabIndex={-1}
onClick={() => goToUser(user)}
>
<UserIcon user={user} showName />
</DropdownItem>
</li>
))}
</DropdownMenu>
</Dropdown>
}
/>
<Dropdown id="online-users" className="online-users" align="end">
<DropdownToggle
as={DropDownToggleButton}
onlineUserCount={onlineUsers.length}
/>
<DropdownMenu>
<DropdownHeader aria-hidden="true">
{t('connected_users')}
</DropdownHeader>
{onlineUsers.map((user, index) => (
<li role="none" key={`${user.user_id}_${index}`}>
<DropdownItem
as="button"
tabIndex={-1}
onClick={() => goToUser(user)}
>
<UserIcon user={user} showName />
</DropdownItem>
</li>
))}
</DropdownMenu>
</Dropdown>
)
} else {
return (
@@ -150,10 +117,7 @@ const DropDownToggleButton = React.forwardRef((props, ref) => {
ref={ref}
>
<strong>{props.onlineUserCount}</strong>&nbsp;
<BootstrapVersionSwitcher
bs3={<Icon type="users" fw />}
bs5={<MaterialIcon type="groups" />}
/>
<MaterialIcon type="groups" />
</button>
</OLTooltip>
)
@@ -1,11 +1,9 @@
import { useEffect, useState, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import classNames from 'classnames'
import Icon from '../../../shared/components/icon'
import OLFormControl from '@/features/ui/components/ol/ol-form-control'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
type ProjectNameEditableLabelProps = {
projectName: string
@@ -90,10 +88,7 @@ function ProjectNameEditableLabel({
>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus */}
<a className="rename" role="button" onClick={startRenaming}>
<BootstrapVersionSwitcher
bs3={<Icon type="pencil" fw />}
bs5={<MaterialIcon type="edit" className="align-text-bottom" />}
/>
<MaterialIcon type="edit" className="align-text-bottom" />
</a>
</OLTooltip>
)}
@@ -1,8 +1,6 @@
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function ShareProjectButton({ onClick }) {
const { t } = useTranslation()
@@ -10,10 +8,7 @@ function ShareProjectButton({ onClick }) {
return (
<div className="toolbar-item">
<button type="button" className="btn btn-full-height" onClick={onClick}>
<BootstrapVersionSwitcher
bs3={<Icon type="group" fw />}
bs5={<MaterialIcon type="group_add" className="align-middle" />}
/>
<MaterialIcon type="group_add" className="align-middle" />
<p className="toolbar-label">{t('share')}</p>
</button>
</div>
@@ -16,7 +16,6 @@ import importOverleafModules from '../../../../macros/import-overleaf-module.mac
import BackToEditorButton from './back-to-editor-button'
import getMeta from '@/utils/meta'
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
const [publishModalModules] = importOverleafModules('publishModal')
const PublishButton = publishModalModules?.import.default
@@ -76,14 +75,9 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
)}
</div>
{getMeta('ol-showUpgradePrompt') && (
<BootstrapVersionSwitcher
bs3={<UpgradePrompt />}
bs5={
<div className="d-flex align-items-center">
<UpgradePrompt />
</div>
}
/>
<div className="d-flex align-items-center">
<UpgradePrompt />
</div>
)}
<ProjectNameEditableLabel
className="toolbar-center"
@@ -96,14 +90,9 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
<OnlineUsersWidget onlineUsers={onlineUsers} goToUser={goToUser} />
{historyIsOpen ? (
<BootstrapVersionSwitcher
bs3={<BackToEditorButton onClick={toggleHistoryOpen} />}
bs5={
<div className="d-flex align-items-center">
<BackToEditorButton onClick={toggleHistoryOpen} />
</div>
}
/>
<div className="d-flex align-items-center">
<BackToEditorButton onClick={toggleHistoryOpen} />
</div>
) : (
<>
{trackChangesVisible && (
@@ -1,7 +1,6 @@
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { useTranslation } from 'react-i18next'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
function TrackChangesToggleButton({
@@ -23,10 +22,7 @@ function TrackChangesToggleButton({
className={classes}
onMouseDown={onMouseDown}
>
<BootstrapVersionSwitcher
bs3={<i className="review-icon" />}
bs5={<MaterialIcon type="rate_review" className="align-middle" />}
/>
<MaterialIcon type="rate_review" className="align-middle" />
<p className="toolbar-label">{t('review')}</p>
</button>
</div>
@@ -1,8 +1,6 @@
import { useTranslation } from 'react-i18next'
import * as eventTracking from '../../../infrastructure/event-tracking'
import OLButton from '@/features/ui/components/ol/ol-button'
import { bsVersion } from '@/features/utils/bootstrap-5'
import classnames from 'classnames'
function UpgradePrompt() {
const { t } = useTranslation()
@@ -16,10 +14,7 @@ function UpgradePrompt() {
<OLButton
variant="primary"
size="sm"
className={classnames(
'toolbar-header-upgrade-prompt',
bsVersion({ bs3: 'btn-xs' })
)}
className="toolbar-header-upgrade-prompt"
href="/user/subscription/plans?itm_referrer=editor-header-upgrade-prompt"
target="_blank"
onClick={handleClick}
@@ -9,7 +9,6 @@ import { useFileTreeData } from '@/shared/context/file-tree-data-context'
import { useFileTreeMainContext } from '../contexts/file-tree-main'
import FileTreeItemMenuItems from './file-tree-item/file-tree-item-menu-items'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function FileTreeContextMenu() {
const { fileTreeReadOnly } = useFileTreeData()
@@ -47,10 +46,6 @@ function FileTreeContextMenu() {
if (!wantOpen) close()
}
function handleClick() {
handleToggle(false)
}
// A11y - Close the context menu when the user presses the Tab key
// Focus should move to the next element in the filetree
function handleKeyDown(event: React.KeyboardEvent<BS3Dropdown | Element>) {
@@ -60,51 +55,27 @@ function FileTreeContextMenu() {
}
return ReactDOM.createPortal(
<BootstrapVersionSwitcher
bs3={
<BS3Dropdown
onClick={handleClick}
open
<div style={contextMenuCoords} className="context-menu">
<Dropdown
show
drop={
document.body.offsetHeight / contextMenuCoords.top < 2 &&
document.body.offsetHeight - contextMenuCoords.top < 250
? 'up'
: 'down'
}
focusFirstItemOnShow // A11y - Focus the first item in the context menu when it opens since the menu is rendered at the root level
onKeyDown={handleKeyDown}
onToggle={handleToggle}
>
<DropdownMenu
className="dropdown-menu-sm-width"
id="dropdown-file-tree-context-menu"
onToggle={handleToggle}
dropup={
document.body.offsetHeight / contextMenuCoords.top < 2 &&
document.body.offsetHeight - contextMenuCoords.top < 250
}
className="context-menu"
style={contextMenuCoords}
onKeyDown={handleKeyDown}
>
<FakeDropDownToggle bsRole="toggle" />
<BS3Dropdown.Menu tabIndex={-1}>
<FileTreeItemMenuItems />
</BS3Dropdown.Menu>
</BS3Dropdown>
}
bs5={
<div style={contextMenuCoords} className="context-menu">
<Dropdown
show
drop={
document.body.offsetHeight / contextMenuCoords.top < 2 &&
document.body.offsetHeight - contextMenuCoords.top < 250
? 'up'
: 'down'
}
focusFirstItemOnShow // A11y - Focus the first item in the context menu when it opens since the menu is rendered at the root level
onKeyDown={handleKeyDown}
onToggle={handleToggle}
>
<DropdownMenu
className="dropdown-menu-sm-width"
id="dropdown-file-tree-context-menu"
>
<FileTreeItemMenuItems />
</DropdownMenu>
</Dropdown>
</div>
}
/>,
<FileTreeItemMenuItems />
</DropdownMenu>
</Dropdown>
</div>,
document.body
)
}
@@ -11,7 +11,6 @@ import importOverleafModules from '../../../../../macros/import-overleaf-module.
import { lazy, Suspense } from 'react'
import { FullSizeLoadingSpinner } from '@/shared/components/loading-spinner'
import getMeta from '@/utils/meta'
import { bsVersion } from '@/features/utils/bootstrap-5'
const createFileModeModules = importOverleafModules('createFileModes')
@@ -40,7 +39,7 @@ export default function FileTreeModalCreateFileBody() {
<ul className="list-unstyled">
<FileTreeModalCreateFileMode
mode="doc"
icon={bsVersion({ bs5: 'description', bs3: 'file' })}
icon="description"
label={t('new_file')}
/>
@@ -54,7 +53,7 @@ export default function FileTreeModalCreateFileBody() {
hasLinkedProjectOutputFileFeature) && (
<FileTreeModalCreateFileMode
mode="project"
icon={bsVersion({ bs5: 'folder_open', bs3: 'folder-open' })}
icon="folder_open"
label={t('from_another_project')}
/>
)}
@@ -66,7 +66,6 @@ export function FileTreeModalCreateFileFooterContent({
form="create-file"
disabled={inFlight || !valid}
isLoading={inFlight}
bs3Props={{ loading: inFlight ? `${t('creating')}` : t('create') }}
>
{t('create')}
</OLButton>
@@ -1,10 +1,8 @@
import classnames from 'classnames'
import PropTypes from 'prop-types'
import Icon from '../../../../shared/components/icon'
import { useFileTreeActionable } from '../../contexts/file-tree-actionable'
import * as eventTracking from '../../../../infrastructure/event-tracking'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export default function FileTreeModalCreateFileMode({ mode, icon, label }) {
@@ -22,10 +20,7 @@ export default function FileTreeModalCreateFileMode({ mode, icon, label }) {
onClick={handleClick}
className="modal-new-file-mode"
>
<BootstrapVersionSwitcher
bs3={<Icon type={icon} fw />}
bs5={<MaterialIcon type={icon} />}
/>
<MaterialIcon type={icon} />
&nbsp;
{label}
</OLButton>
@@ -5,7 +5,6 @@ import {
useMemo,
FormEventHandler,
} from 'react'
import Icon from '../../../../../shared/components/icon'
import FileTreeCreateNameInput from '../file-tree-create-name-input'
import { useTranslation } from 'react-i18next'
import { useUserProjects } from '../../../hooks/use-user-projects'
@@ -25,7 +24,6 @@ import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
import OLFormLabel from '@/features/ui/components/ol/ol-form-label'
import OLForm from '@/features/ui/components/ol/ol-form'
import OLFormSelect from '@/features/ui/components/ol/ol-form-select'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { Spinner } from 'react-bootstrap-5'
export default function FileTreeImportFromProject() {
@@ -216,16 +214,11 @@ function SelectProject({
{loading && (
<span>
&nbsp;
<BootstrapVersionSwitcher
bs3={<Icon type="spinner" spin />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
</span>
)}
@@ -287,16 +280,11 @@ function SelectProjectOutputFile({
{loading && (
<span>
&nbsp;
<BootstrapVersionSwitcher
bs3={<Icon type="spinner" spin />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
</span>
)}
@@ -351,16 +339,11 @@ function SelectProjectEntity({
{loading && (
<span>
&nbsp;
<BootstrapVersionSwitcher
bs3={<Icon type="spinner" spin />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
</span>
)}
@@ -1,6 +1,4 @@
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import { useFeatureFlag } from '@/shared/context/split-test-context'
@@ -33,44 +31,21 @@ function FileTreeFolderIcons({
}
return (
<BootstrapVersionSwitcher
bs3={
<>
<button
onClick={onExpandCollapseClick}
aria-label={expanded ? t('collapse') : t('expand')}
>
<Icon
type={expanded ? 'angle-down' : 'angle-right'}
fw
className="file-tree-expand-icon"
/>
</button>
<Icon
type={expanded ? 'folder-open' : 'folder'}
fw
className="file-tree-folder-icon"
/>
</>
}
bs5={
<>
<button
onClick={onExpandCollapseClick}
aria-label={expanded ? t('collapse') : t('expand')}
>
<MaterialIcon
type={expanded ? 'expand_more' : 'chevron_right'}
className="file-tree-expand-icon"
/>
</button>
<MaterialIcon
type={expanded ? 'folder_open' : 'folder'}
className="file-tree-folder-icon"
/>
</>
}
/>
<>
<button
onClick={onExpandCollapseClick}
aria-label={expanded ? t('collapse') : t('expand')}
>
<MaterialIcon
type={expanded ? 'expand_more' : 'chevron_right'}
className="file-tree-expand-icon"
/>
</button>
<MaterialIcon
type={expanded ? 'folder_open' : 'folder'}
className="file-tree-folder-icon"
/>
</>
)
}
@@ -1,10 +1,8 @@
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import iconTypeFromName, {
newEditorIconTypeFromName,
} from '../util/icon-type-from-name'
import classnames from 'classnames'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import { useFeatureFlag } from '@/shared/context/split-test-context'
@@ -46,34 +44,15 @@ function FileTreeIcon({
return (
<>
&nbsp;
<BootstrapVersionSwitcher
bs3={
<>
<Icon type={iconTypeFromName(name)} fw className={className} />
{isLinkedFile && (
<Icon
type="external-link-square"
modifier="rotate-180"
className="linked-file-highlight"
accessibilityLabel={t('linked_file')}
/>
)}
</>
}
bs5={
<>
<MaterialIcon type={iconTypeFromName(name)} className={className} />
{isLinkedFile && (
<MaterialIcon
type="open_in_new"
modifier="rotate-180"
className="linked-file-highlight"
accessibilityLabel={t('linked_file')}
/>
)}
</>
}
/>
<MaterialIcon type={iconTypeFromName(name)} className={className} />
{isLinkedFile && (
<MaterialIcon
type="open_in_new"
modifier="rotate-180"
className="linked-file-highlight"
accessibilityLabel={t('linked_file')}
/>
)}
</>
)
}
@@ -3,13 +3,11 @@ import { useTranslation } from 'react-i18next'
import * as eventTracking from '../../../../infrastructure/event-tracking'
import { useProjectContext } from '@/shared/context/project-context'
import { MenuItem } from 'react-bootstrap'
import {
DropdownDivider,
DropdownItem,
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import { useFileTreeActionable } from '../../contexts/file-tree-actionable'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function FileTreeItemMenuItems() {
const { t } = useTranslation()
@@ -47,82 +45,49 @@ function FileTreeItemMenuItems() {
}, [startUploadingDocOrFile])
return (
<BootstrapVersionSwitcher
bs3={
<>
{canRename ? (
<li role="none">
<DropdownItem onClick={startRenaming}>{t('rename')}</DropdownItem>
</li>
) : null}
{downloadPath ? (
<li role="none">
<DropdownItem
href={downloadPath}
onClick={downloadWithAnalytics}
download={selectedFileName ?? undefined}
>
{t('download')}
</DropdownItem>
</li>
) : null}
{canDelete ? (
<li role="none">
<DropdownItem onClick={startDeleting}>{t('delete')}</DropdownItem>
</li>
) : null}
{canCreate ? (
<>
{canRename ? (
<MenuItem onClick={startRenaming}>{t('rename')}</MenuItem>
) : null}
{downloadPath ? (
<MenuItem
href={downloadPath}
onClick={downloadWithAnalytics}
download={selectedFileName}
>
{t('download')}
</MenuItem>
) : null}
{canDelete ? (
<MenuItem onClick={startDeleting}>{t('delete')}</MenuItem>
) : null}
{canCreate ? (
<>
<li role="none" className="divider" />
<MenuItem onClick={createWithAnalytics}>{t('new_file')}</MenuItem>
<MenuItem onClick={startCreatingFolder}>
{t('new_folder')}
</MenuItem>
<MenuItem onClick={uploadWithAnalytics}>{t('upload')}</MenuItem>
</>
) : null}
<DropdownDivider />
<li role="none">
<DropdownItem onClick={createWithAnalytics}>
{t('new_file')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem onClick={startCreatingFolder}>
{t('new_folder')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem onClick={uploadWithAnalytics}>
{t('upload')}
</DropdownItem>
</li>
</>
}
bs5={
<>
{canRename ? (
<li role="none">
<DropdownItem onClick={startRenaming}>{t('rename')}</DropdownItem>
</li>
) : null}
{downloadPath ? (
<li role="none">
<DropdownItem
href={downloadPath}
onClick={downloadWithAnalytics}
download={selectedFileName ?? undefined}
>
{t('download')}
</DropdownItem>
</li>
) : null}
{canDelete ? (
<li role="none">
<DropdownItem onClick={startDeleting}>{t('delete')}</DropdownItem>
</li>
) : null}
{canCreate ? (
<>
<DropdownDivider />
<li role="none">
<DropdownItem onClick={createWithAnalytics}>
{t('new_file')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem onClick={startCreatingFolder}>
{t('new_folder')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem onClick={uploadWithAnalytics}>
{t('upload')}
</DropdownItem>
</li>
</>
) : null}
</>
}
/>
) : null}
</>
)
}
@@ -1,8 +1,6 @@
import { useRef } from 'react'
import { useTranslation } from 'react-i18next'
import Icon from '../../../../shared/components/icon'
import { useFileTreeMainContext } from '../../contexts/file-tree-main'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
function FileTreeItemMenu({ id, name }: { id: string; name: string }) {
@@ -36,10 +34,7 @@ function FileTreeItemMenu({ id, name }: { id: string; name: string }) {
aria-expanded={isMenuOpen}
aria-label={t('open_action_menu', { name })}
>
<BootstrapVersionSwitcher
bs3={<Icon type="ellipsis-v" accessibilityLabel={t('menu')} />}
bs5={<MaterialIcon type="more_vert" accessibilityLabel={t('menu')} />}
/>
<MaterialIcon type="more_vert" accessibilityLabel={t('menu')} />
</button>
</div>
)
@@ -1,10 +1,8 @@
import { useTranslation } from 'react-i18next'
import * as eventTracking from '../../../infrastructure/event-tracking'
import Icon from '../../../shared/components/icon'
import { useFileTreeActionable } from '../contexts/file-tree-actionable'
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import OLButtonToolbar from '@/features/ui/components/ol/ol-button-toolbar'
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
@@ -60,15 +58,7 @@ function FileTreeToolbarLeft() {
overlayProps={{ placement: 'bottom' }}
>
<button className="btn" onClick={createWithAnalytics}>
<BootstrapVersionSwitcher
bs5={
<MaterialIcon
type="description"
accessibilityLabel={t('new_file')}
/>
}
bs3={<Icon type="file" fw accessibilityLabel={t('new_file')} />}
/>
<MaterialIcon type="description" accessibilityLabel={t('new_file')} />
</button>
</OLTooltip>
<OLTooltip
@@ -77,15 +67,7 @@ function FileTreeToolbarLeft() {
overlayProps={{ placement: 'bottom' }}
>
<button className="btn" onClick={startCreatingFolder} tabIndex={-1}>
<BootstrapVersionSwitcher
bs5={
<MaterialIcon
type="folder"
accessibilityLabel={t('new_folder')}
/>
}
bs3={<Icon type="folder" fw accessibilityLabel={t('new_folder')} />}
/>
<MaterialIcon type="folder" accessibilityLabel={t('new_folder')} />
</button>
</OLTooltip>
<OLTooltip
@@ -94,12 +76,7 @@ function FileTreeToolbarLeft() {
overlayProps={{ placement: 'bottom' }}
>
<button className="btn" onClick={uploadWithAnalytics} tabIndex={-1}>
<BootstrapVersionSwitcher
bs5={
<MaterialIcon type="upload" accessibilityLabel={t('upload')} />
}
bs3={<Icon type="upload" fw accessibilityLabel={t('upload')} />}
/>
<MaterialIcon type="upload" accessibilityLabel={t('upload')} />
</button>
</OLTooltip>
</div>
@@ -126,12 +103,7 @@ function FileTreeToolbarRight() {
overlayProps={{ placement: 'bottom' }}
>
<button className="btn" onClick={startRenaming} tabIndex={-1}>
<BootstrapVersionSwitcher
bs3={<Icon type="pencil" fw accessibilityLabel={t('rename')} />}
bs5={
<MaterialIcon type="edit" accessibilityLabel={t('rename')} />
}
/>
<MaterialIcon type="edit" accessibilityLabel={t('rename')} />
</button>
</OLTooltip>
) : null}
@@ -143,12 +115,7 @@ function FileTreeToolbarRight() {
overlayProps={{ placement: 'bottom' }}
>
<button className="btn" onClick={startDeleting} tabIndex={-1}>
<BootstrapVersionSwitcher
bs3={<Icon type="trash-o" fw accessibilityLabel={t('delete')} />}
bs5={
<MaterialIcon type="delete" accessibilityLabel={t('delete')} />
}
/>
<MaterialIcon type="delete" accessibilityLabel={t('delete')} />
</button>
</OLTooltip>
) : null}
@@ -83,12 +83,7 @@ function FileTreeModalCreateFolder() {
<OLModalFooter>
{inFlight ? (
<OLButton
variant="primary"
disabled
isLoading={inFlight}
bs3Props={{ loading: `${t('creating')}` }}
/>
<OLButton variant="primary" disabled isLoading={inFlight} />
) : (
<>
<OLButton variant="secondary" onClick={handleHide}>
@@ -55,12 +55,7 @@ function FileTreeModalDelete() {
<OLModalFooter>
{inFlight ? (
<OLButton
variant="danger"
disabled
isLoading
bs3Props={{ loading: `${t('deleting')}` }}
/>
<OLButton variant="danger" disabled isLoading />
) : (
<>
<OLButton variant="secondary" onClick={handleHide}>
@@ -1,4 +1,3 @@
import { isBootstrap5 } from '@/features/utils/bootstrap-5'
import { AvailableUnfilledIcon } from '@/shared/components/material-icon'
// TODO ide-redesign-cleanup: Make this the default export and remove the legacy version
@@ -27,12 +26,12 @@ export default function iconTypeFromName(name: string): string {
if (ext && ['png', 'pdf', 'jpg', 'jpeg', 'gif'].includes(ext)) {
return 'image'
} else if (ext && ['csv', 'xls', 'xlsx'].includes(ext)) {
return isBootstrap5() ? 'table_chart' : 'table'
return 'table_chart'
} else if (ext && ['py', 'r'].includes(ext)) {
return isBootstrap5() ? 'code' : 'file-text'
return 'code'
} else if (ext && ['bib'].includes(ext)) {
return isBootstrap5() ? 'menu_book' : 'book'
return 'menu_book'
} else {
return isBootstrap5() ? 'description' : 'file'
return 'description'
}
}
@@ -1,7 +1,6 @@
import { useState, type ElementType } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import { formatTime, relativeDate } from '../../utils/format-date'
import { fileUrl } from '../../utils/fileUrl'
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
@@ -14,7 +13,6 @@ import { BinaryFile, hasProvider, LinkedFile } from '../types/binary-file'
import FileViewRefreshButton from './file-view-refresh-button'
import FileViewRefreshError from './file-view-refresh-error'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import OLButton from '@/features/ui/components/ol/ol-button'
const tprFileViewInfo = importOverleafModules('tprFileViewInfo') as {
@@ -87,10 +85,7 @@ export default function FileViewHeader({ file }: FileViewHeaderProps) {
download={file.name}
href={fileUrl(projectId, file.id, file.hash)}
>
<BootstrapVersionSwitcher
bs3={<Icon type="download" fw />}
bs5={<MaterialIcon type="download" className="align-middle" />}
/>{' '}
<MaterialIcon type="download" className="align-middle" />{' '}
<span>{t('download')}</span>
</OLButton>
</div>
@@ -1,26 +1,12 @@
import Icon from '../../../shared/components/icon'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
export const LinkedFileIcon = props => {
return (
<BootstrapVersionSwitcher
bs3={
<Icon
type="external-link-square"
modifier="rotate-180"
className="linked-file-icon"
{...props}
/>
}
bs5={
<MaterialIcon
type="open_in_new"
modifier="rotate-180"
className="align-middle linked-file-icon"
{...props}
/>
}
<MaterialIcon
type="open_in_new"
modifier="rotate-180"
className="align-middle linked-file-icon"
{...props}
/>
)
}
@@ -6,7 +6,6 @@ import {
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import Icon from '@/shared/components/icon'
import { postJSON } from '@/infrastructure/fetch-json'
import { useProjectContext } from '@/shared/context/project-context'
import type { BinaryFile } from '../types/binary-file'
@@ -103,14 +102,7 @@ function FileViewRefreshButtonDefault({
onClick={() => refreshFile(null)}
disabled={refreshing}
isLoading={refreshing}
bs3Props={{
loading: (
<>
<Icon type="refresh" spin={refreshing} fw />{' '}
<span>{refreshing ? `${t('refreshing')}` : t('refresh')}</span>
</>
),
}}
loadingLabel={t('refreshing')}
>
{t('refresh')}
</OLButton>
@@ -117,11 +117,6 @@ function AddLabelModal({ show, setShow, version }: AddLabelModalProps) {
variant="primary"
disabled={isLoading || !comment.length}
isLoading={isLoading}
bs3Props={{
loading: isLoading
? t('history_adding_label')
: t('history_add_label'),
}}
>
{t('history_add_label')}
</OLButton>
@@ -192,11 +192,9 @@ function AllHistoryList() {
},
],
}}
bs3Props={{ shouldUpdatePosition: true }}
>
<OLPopover
id="popover-react-history-tutorial"
bs3Props={{ arrowOffsetTop: 10 }}
title={
<span>
{t('react_history_tutorial_title')}{' '}
@@ -236,11 +234,9 @@ function AllHistoryList() {
onHide={hidePopover}
// using scrollerRef to position the popover in the middle of the viewport
target={scrollerRef.current}
bs3Props={{ shouldUpdatePosition: true }}
>
<OLPopover
id="popover-history-restore-promo"
bs3Props={{ arrowOffsetTop: 10 }}
title={
<span>
{t('history_restore_promo_title')}
@@ -1,13 +1,9 @@
import React, { useRef, useEffect, ReactNode } from 'react'
import { Dropdown as BS3Dropdown } from 'react-bootstrap'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import React, { ReactNode } from 'react'
import {
Dropdown,
DropdownMenu,
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import BS3DropdownToggleWithTooltip from '../../../../ui/components/bootstrap-3/dropdown-toggle-with-tooltip'
import BS5DropdownToggleWithTooltip from '@/features/ui/components/bootstrap-5/dropdown-toggle-with-tooltip'
import DropdownMenuWithRef from '../../../../ui/components/bootstrap-3/dropdown-menu-with-ref'
type ActionDropdownProps = {
id: string
@@ -19,70 +15,6 @@ type ActionDropdownProps = {
setIsOpened: (isOpened: boolean) => void
}
function BS3ActionsDropdown({
id,
children,
parentSelector,
isOpened,
iconTag,
setIsOpened,
toolTipDescription,
}: ActionDropdownProps) {
const menuRef = useRef<HTMLElement>()
// handle the placement of the dropdown above or below the toggle button
useEffect(() => {
if (menuRef.current && parentSelector) {
const parent = menuRef.current.closest(parentSelector)
if (!parent) {
return
}
const parentBottom = parent.getBoundingClientRect().bottom
const { top, height } = menuRef.current.getBoundingClientRect()
if (top + height > parentBottom) {
menuRef.current.style.bottom = '100%'
menuRef.current.style.top = 'auto'
} else {
menuRef.current.style.bottom = 'auto'
menuRef.current.style.top = '100%'
}
}
})
return (
<BS3Dropdown
id={`history-version-dropdown-${id}`}
pullRight
open={isOpened}
onToggle={open => setIsOpened(open)}
className="pull-right"
>
<BS3DropdownToggleWithTooltip
bsRole="toggle"
className="history-version-dropdown-menu-btn"
isOpened={isOpened}
tooltipProps={{
id,
description: toolTipDescription,
overlayProps: { placement: 'bottom', trigger: ['hover'] },
}}
>
{iconTag}
</BS3DropdownToggleWithTooltip>
<DropdownMenuWithRef
bsRole="menu"
className="history-version-dropdown-menu"
menuRef={menuRef}
>
{children}
</DropdownMenuWithRef>
</BS3Dropdown>
)
}
function BS5ActionsDropdown({
id,
children,
@@ -116,12 +48,7 @@ function BS5ActionsDropdown({
}
function ActionsDropdown(props: ActionDropdownProps) {
return (
<BootstrapVersionSwitcher
bs3={<BS3ActionsDropdown {...props} />}
bs5={<BS5ActionsDropdown {...props} />}
/>
)
return <BS5ActionsDropdown {...props} />
}
export default ActionsDropdown
@@ -1,8 +1,6 @@
import ActionsDropdown from './actions-dropdown'
import Icon from '../../../../../shared/components/icon'
import { useTranslation } from 'react-i18next'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
type HistoryDropdownProps = {
children: React.ReactNode
@@ -25,17 +23,7 @@ function HistoryDropdown({
toolTipDescription={t('more_actions')}
setIsOpened={setIsOpened}
iconTag={
<BootstrapVersionSwitcher
bs3={
<Icon type="ellipsis-v" accessibilityLabel={t('more_actions')} />
}
bs5={
<MaterialIcon
type="more_vert"
accessibilityLabel={t('more_actions')}
/>
}
/>
<MaterialIcon type="more_vert" accessibilityLabel={t('more_actions')} />
}
parentSelector="[data-history-version-list-container]"
>
@@ -2,7 +2,6 @@ import { useHistoryContext } from '../../../../context/history-context'
import { UpdateRange } from '../../../../services/types/update'
import { ReactNode } from 'react'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import { bsVersion } from '@/features/utils/bootstrap-5'
type CompareProps = {
comparisonRange: UpdateRange
@@ -38,9 +37,7 @@ function Compare({
overlayProps={{ placement: 'left' }}
>
<button className="history-compare-btn" onClick={handleCompareVersion}>
<span className={bsVersion({ bs3: 'sr-only', bs5: 'visually-hidden' })}>
{toolTipDescription}
</span>
<span className="visually-hidden">{toolTipDescription}</span>
{icon}
</button>
</OLTooltip>
@@ -1,8 +1,6 @@
import { useTranslation } from 'react-i18next'
import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import Icon from '../../../../../../shared/components/icon'
type DownloadProps = {
projectId: string
@@ -24,12 +22,7 @@ function Download({
download={`${projectId}_v${version}.zip`}
rel="noreferrer"
onClick={closeDropdown}
leadingIcon={
<BootstrapVersionSwitcher
bs3={<Icon type="cloud-download" fw />}
bs5={<MaterialIcon type="download" />}
/>
}
leadingIcon={<MaterialIcon type="download" />}
{...props}
>
{t('history_download_this_version')}
@@ -1,4 +1,3 @@
import Icon from '@/shared/components/icon'
import { useCallback, useState } from 'react'
import OLDropdownMenuItem from '@/features/ui/components/ol/ol-dropdown-menu-item'
import { useTranslation } from 'react-i18next'
@@ -8,7 +7,6 @@ import { useRestoreProject } from '@/features/history/context/hooks/use-restore-
import withErrorBoundary from '@/infrastructure/error-boundary'
import { RestoreProjectErrorModal } from '../../../diff-view/modals/restore-project-error-modal'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
type RestoreProjectProps = {
projectId: string
@@ -48,12 +46,7 @@ const RestoreProject = ({
<>
<OLDropdownMenuItem
as="button"
leadingIcon={
<BootstrapVersionSwitcher
bs3={<Icon type="undo" fw />}
bs5={<MaterialIcon type="undo" />}
/>
}
leadingIcon={<MaterialIcon type="undo" />}
onClick={handleClick}
>
{t('restore_project_to_this_version')}
@@ -22,7 +22,6 @@ import { CompareVersionDropdownContentAllHistory } from './dropdown/compare-vers
import FileRestoreChange from './file-restore-change'
import HistoryResyncChange from './history-resync-change'
import ProjectRestoreChange from './project-restore-change'
import { bsVersion } from '@/features/utils/bootstrap-5'
type HistoryVersionProps = {
update: LoadedUpdate
@@ -124,10 +123,7 @@ function HistoryVersion({
)}
{selectionState !== 'selected' && !faded ? (
<div
data-testid="compare-icon-version"
className={bsVersion({ bs3: 'pull-right', bs5: 'float-end' })}
>
<div data-testid="compare-icon-version" className="float-end">
{selectionState !== 'withinSelected' ? (
<CompareItems
updateRange={updateRange}
@@ -13,7 +13,6 @@ import { ItemSelectionState } from '../../utils/history-details'
import CompareVersionDropdown from './dropdown/compare-version-dropdown'
import { CompareVersionDropdownContentLabelsList } from './dropdown/compare-version-dropdown-content'
import HistoryDropdownContent from '@/features/history/components/change-list/dropdown/history-dropdown-content'
import { bsVersion } from '@/features/utils/bootstrap-5'
type LabelListItemProps = {
version: Version
@@ -97,10 +96,7 @@ function LabelListItem({
) : null}
</HistoryDropdown>
{selectionState !== 'selected' ? (
<div
data-testid="compare-icon-version"
className={bsVersion({ bs3: 'pull-right', bs5: 'float-end' })}
>
<div data-testid="compare-icon-version" className="float-end">
{selectionState !== 'withinSelected' ? (
<CompareItems
updateRange={updateRange}
@@ -122,11 +122,6 @@ const ChangeTag = forwardRef<HTMLElement, TagProps>(
disabled={isLoading}
isLoading={isLoading}
onClick={localDeleteHandler}
bs3Props={{
loading: isLoading
? t('history_deleting_label')
: t('history_delete_label'),
}}
>
{t('history_delete_label')}
</OLButton>
@@ -21,7 +21,6 @@ import {
import { useTranslation } from 'react-i18next'
import { inlineBackground } from '../../../source-editor/extensions/inline-background'
import OLButton from '@/features/ui/components/ol/ol-button'
import { bsVersion } from '@/features/utils/bootstrap-5'
function extensions(themeOptions: Options): Extension[] {
return [
@@ -134,7 +133,7 @@ function DocumentDiffViewer({
{before > 0 ? (
<OLButton
variant="secondary"
leadingIcon={bsVersion({ bs3: 'arrow-up', bs5: 'arrow_upward' })}
leadingIcon="arrow_upward"
onClick={scrollToPrevious}
className="previous-highlight-button"
>
@@ -144,7 +143,7 @@ function DocumentDiffViewer({
{after > 0 ? (
<OLButton
variant="secondary"
leadingIcon={bsVersion({ bs3: 'arrow-down', bs5: 'arrow_downward' })}
leadingIcon="arrow_downward"
onClick={scrollToNext}
className="next-highlight-button"
>
@@ -51,7 +51,6 @@ export const RestoreProjectModal = ({
onClick={onRestore}
disabled={isRestoring}
isLoading={isRestoring}
bs3Props={{ loading: isRestoring ? t('restoring') : t('restore') }}
>
{t('restore')}
</OLButton>
@@ -21,10 +21,6 @@ export default function ToolbarRestoreFileButton({
className="history-react-toolbar-restore-file-button"
isLoading={isLoading}
onClick={() => restoreDeletedFile(selection)}
bs3Props={{
bsSize: 'xsmall',
loading: isLoading ? `${t('restoring')}` : t('restore_file'),
}}
>
{t('restore_file')}
</OLButton>
@@ -38,10 +38,6 @@ function ToolbarRestoreFileToVersionButton({
size="sm"
isLoading={isLoading}
onClick={() => setShowConfirmModal(true)}
bs3Props={{
bsSize: 'xsmall',
loading: isLoading ? `${t('restoring')}` : t('restore_file_version'),
}}
>
{t('restore_file_version')}
</OLButton>
@@ -2,9 +2,7 @@ import { memo } from 'react'
import classNames from 'classnames'
import HistoryFileTreeItem from './history-file-tree-item'
import iconTypeFromName from '../../../file-tree/util/icon-type-from-name'
import Icon from '../../../../shared/components/icon'
import type { FileDiff } from '../../services/types/file'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
type HistoryFileTreeDocProps = {
@@ -36,20 +34,9 @@ function HistoryFileTreeDoc({
name={name}
operation={'operation' in file ? file.operation : undefined}
icons={
<BootstrapVersionSwitcher
bs3={
<Icon
type={iconTypeFromName(name)}
fw
className="file-tree-icon"
/>
}
bs5={
<MaterialIcon
type={iconTypeFromName(name)}
className="file-tree-icon"
/>
}
<MaterialIcon
type={iconTypeFromName(name)}
className="file-tree-icon"
/>
}
/>
@@ -4,9 +4,7 @@ import { useTranslation } from 'react-i18next'
import HistoryFileTreeItem from './history-file-tree-item'
import HistoryFileTreeFolderList from './history-file-tree-folder-list'
import Icon from '../../../../shared/components/icon'
import type { HistoryDoc, HistoryFileTree } from '../../utils/file-tree'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
type HistoryFileTreeFolderProps = {
@@ -43,46 +41,22 @@ function HistoryFileTreeFolder({
})
const icons = (
<BootstrapVersionSwitcher
bs3={
<>
<button
onClick={() => setExpanded(!expanded)}
aria-label={expanded ? t('collapse') : t('expand')}
className="history-file-tree-folder-button"
>
<Icon
type={expanded ? 'angle-down' : 'angle-right'}
fw
className="file-tree-expand-icon"
/>
</button>
<Icon
type={expanded ? 'folder-open' : 'folder'}
fw
className="file-tree-folder-icon"
/>
</>
}
bs5={
<>
<button
onClick={() => setExpanded(!expanded)}
aria-label={expanded ? t('collapse') : t('expand')}
className="history-file-tree-folder-button"
>
<MaterialIcon
type={expanded ? 'expand_more' : 'chevron_right'}
className="file-tree-expand-icon"
/>
</button>
<MaterialIcon
type={expanded ? 'folder_open' : 'folder'}
className="file-tree-folder-icon"
/>
</>
}
/>
<>
<button
onClick={() => setExpanded(!expanded)}
aria-label={expanded ? t('collapse') : t('expand')}
className="history-file-tree-folder-button"
>
<MaterialIcon
type={expanded ? 'expand_more' : 'chevron_right'}
className="file-tree-expand-icon"
/>
</button>
<MaterialIcon
type={expanded ? 'folder_open' : 'folder'}
className="file-tree-folder-icon"
/>
</>
)
return (
@@ -61,7 +61,6 @@ export function Alerts() {
id="synctex-more-info-button"
variant="secondary"
size="sm"
bs3Props={{ className: 'alert-link-as-btn pull-right' }}
>
{t('more_info')}
</OLButton>
@@ -40,7 +40,6 @@ export function LostConnectionAlert({
onClick={() => tryReconnectNow()}
size="sm"
variant="secondary"
bs3Props={{ className: 'pull-right' }}
>
{t('try_now')}
</OLButton>
@@ -1,12 +1,9 @@
import { useTranslation } from 'react-i18next'
import { memo } from 'react'
import classnames from 'classnames'
import Icon from '../../../shared/components/icon'
import { useDetachCompileContext } from '../../../shared/context/detach-compile-context'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import OLButton from '@/features/ui/components/ol/ol-button'
import { bsVersion } from '@/features/utils/bootstrap-5'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
const modifierKey = /Mac/i.test(navigator.platform) ? 'Cmd' : 'Ctrl'
@@ -14,7 +11,6 @@ function DetachCompileButton() {
const { t } = useTranslation()
const { compiling, startCompile, hasChanges } = useDetachCompileContext()
const compileButtonLabel = compiling ? `${t('compiling')}` : t('recompile')
const tooltipElement = (
<>
{t('recompile_pdf')}{' '}
@@ -23,12 +19,7 @@ function DetachCompileButton() {
)
return (
<div
className={classnames(
'detach-compile-button-container',
bsVersion({ bs5: 'ms-1' })
)}
>
<div className="detach-compile-button-container ms-1">
<OLTooltip
id="detach-compile"
description={tooltipElement}
@@ -45,28 +36,8 @@ function DetachCompileButton() {
})}
size="sm"
isLoading={compiling}
bs3Props={{
loading: compiling && (
<>
<Icon type="refresh" spin={compiling} />
<span className="detach-compile-button-label">
{compileButtonLabel}
</span>
</>
),
}}
>
<BootstrapVersionSwitcher
bs3={
<>
<Icon type="refresh" spin={compiling} />
<span className="detach-compile-button-label">
{compileButtonLabel}
</span>
</>
}
bs5={t('recompile')}
/>
{t('recompile')}
</OLButton>
</OLTooltip>
</div>
@@ -1,9 +1,7 @@
import Icon from '../../../shared/components/icon'
import OLButton from '@/features/ui/components/ol/ol-button'
import { useTranslation } from 'react-i18next'
import { memo } from 'react'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function PdfClearCacheButton() {
const { compiling, clearCache, clearingCache } = useCompileContext()
@@ -19,19 +17,8 @@ function PdfClearCacheButton() {
isLoading={clearingCache}
disabled={clearingCache || compiling}
leadingIcon="delete"
loadingLabel={t('clear_cached_files')}
>
<BootstrapVersionSwitcher
bs3={
<>
{clearingCache ? (
<Icon type="refresh" spin />
) : (
<Icon type="trash-o" />
)}
&nbsp;
</>
}
/>
<span>{t('clear_cached_files')}</span>
</OLButton>
)
@@ -1,28 +1,14 @@
import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import OLNotification from '@/features/ui/components/ol/ol-notification'
import { bsVersion } from '@/features/utils/bootstrap-5'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function PdfCodeCheckFailedNotice() {
const { t } = useTranslation()
return (
<OLNotification
type="error"
content={
<>
<BootstrapVersionSwitcher
bs3={
<>
<Icon type="exclamation-triangle" fw />{' '}
</>
}
/>
{t('code_check_failed_explanation')}
</>
}
className={bsVersion({ bs5: 'm-0', bs3: 'mb-2' })}
content={t('code_check_failed_explanation')}
className="m-0"
/>
)
}
@@ -3,10 +3,7 @@ import { memo } from 'react'
import classNames from 'classnames'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
import SplitMenu from '../../../shared/components/split-menu'
import Icon from '../../../shared/components/icon'
import * as eventTracking from '../../../infrastructure/event-tracking'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import {
DropdownToggleCustom,
@@ -19,7 +16,6 @@ import {
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import OLButton from '@/features/ui/components/ol/ol-button'
import OLButtonGroup from '@/features/ui/components/ol/ol-button-group'
import { bsVersion, isBootstrap5 } from '@/features/utils/bootstrap-5'
import { useLayoutContext } from '@/shared/context/layout-context'
const modifierKey = /Mac/i.test(navigator.platform) ? 'Cmd' : 'Ctrl'
@@ -43,7 +39,6 @@ function PdfCompileButton() {
compiling,
draft,
hasChanges,
setAnimateCompileDropdownArrow,
setAutoCompile,
setDraft,
setStopOnValidationError,
@@ -67,7 +62,6 @@ function PdfCompileButton() {
recompileFromScratch()
}
const compileButtonLabel = compiling ? `${t('compiling')}` : t('recompile')
const tooltipElement = (
<>
{t('recompile_pdf')}{' '}
@@ -81,288 +75,160 @@ function PdfCompileButton() {
'btn-striped-animated': hasChanges,
},
'no-left-border',
bsVersion({ bs5: 'dropdown-button-toggle' })
'dropdown-button-toggle'
)
const buttonClassName = classNames(
'align-items-center py-0 no-left-radius px-3',
{
'btn-striped-animated': hasChanges,
'align-items-center py-0': isBootstrap5(),
},
'no-left-radius px-3'
}
)
return (
<BootstrapVersionSwitcher
bs3={
<SplitMenu
bsStyle="primary"
bsSize="xs"
<Dropdown as={OLButtonGroup} className="compile-button-group">
<OLTooltip
description={tooltipElement}
id="compile"
tooltipProps={{ className: 'keyboard-tooltip' }}
overlayProps={{
delay: { show: 500, hide: 0 },
placement: detachRole === 'detached' ? 'bottom' : undefined,
}}
>
<OLButton
variant="primary"
disabled={compiling}
button={{
tooltip: {
description: tooltipElement,
id: 'compile',
tooltipProps: { className: 'keyboard-tooltip' },
overlayProps: {
delayShow: 500,
placement: detachRole === 'detached' ? 'bottom' : undefined,
},
},
icon: { type: 'refresh', spin: compiling },
onClick: () => startCompile(),
text: compileButtonLabel,
className: buttonClassName,
}}
dropdownToggle={{
'aria-label': t('toggle_compile_options_menu'),
handleAnimationEnd: () => setAnimateCompileDropdownArrow(false),
className: dropdownToggleClassName,
}}
dropdown={{
id: 'pdf-recompile-dropdown',
}}
isLoading={compiling}
onClick={() => startCompile()}
className={buttonClassName}
loadingLabel={`${t('compiling')}`}
>
<SplitMenu.Item header>{t('auto_compile')}</SplitMenu.Item>
{t('recompile')}
</OLButton>
</OLTooltip>
<SplitMenu.Item
onSelect={() =>
<DropdownToggle
as={DropdownToggleCustom}
split
variant="primary"
id="pdf-recompile-dropdown"
size="sm"
aria-label={t('toggle_compile_options_menu')}
className={dropdownToggleClassName}
/>
<DropdownMenu>
<DropdownHeader>{t('auto_compile')}</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(true, setAutoCompile, 'auto-compile')
}
trailingIcon={autoCompile ? 'check' : null}
>
<Icon type={autoCompile ? 'check' : ''} fw />
{t('on')}
</SplitMenu.Item>
<SplitMenu.Item
onSelect={() =>
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(false, setAutoCompile, 'auto-compile')
}
trailingIcon={!autoCompile ? 'check' : null}
>
<Icon type={!autoCompile ? 'check' : ''} fw />
{t('off')}
</SplitMenu.Item>
<SplitMenu.Item header>{t('compile_mode')}</SplitMenu.Item>
<SplitMenu.Item
onSelect={() => sendEventAndSet(false, setDraft, 'compile-mode')}
</DropdownItem>
</li>
<DropdownDivider />
<DropdownHeader>{t('compile_mode')}</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={() => sendEventAndSet(false, setDraft, 'compile-mode')}
trailingIcon={!draft ? 'check' : null}
>
<Icon type={!draft ? 'check' : ''} fw />
{t('normal')}
</SplitMenu.Item>
<SplitMenu.Item
onSelect={() => sendEventAndSet(true, setDraft, 'compile-mode')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={() => sendEventAndSet(true, setDraft, 'compile-mode')}
trailingIcon={draft ? 'check' : null}
>
<Icon type={draft ? 'check' : ''} fw />
{t('fast')} <span className="subdued">[draft]</span>
</SplitMenu.Item>
<SplitMenu.Item header>Syntax Checks</SplitMenu.Item>
<SplitMenu.Item
onSelect={() =>
{t('fast')}&nbsp;<span className="subdued">[draft]</span>
</DropdownItem>
</li>
<DropdownDivider />
<DropdownHeader>Syntax Checks</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(true, setStopOnValidationError, 'syntax-check')
}
trailingIcon={stopOnValidationError ? 'check' : null}
>
<Icon type={stopOnValidationError ? 'check' : ''} fw />
{t('stop_on_validation_error')}
</SplitMenu.Item>
<SplitMenu.Item
onSelect={() =>
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(false, setStopOnValidationError, 'syntax-check')
}
trailingIcon={!stopOnValidationError ? 'check' : null}
>
<Icon type={!stopOnValidationError ? 'check' : ''} fw />
{t('ignore_validation_errors')}
</SplitMenu.Item>
<SplitMenu.Item header>{t('compile_error_handling')}</SplitMenu.Item>
<SplitMenu.Item onSelect={enableStopOnFirstError}>
<Icon type={stopOnFirstError ? 'check' : ''} fw />
</DropdownItem>
</li>
<DropdownDivider />
<DropdownHeader>{t('compile_error_handling')}</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={enableStopOnFirstError}
trailingIcon={stopOnFirstError ? 'check' : null}
>
{t('stop_on_first_error')}
</SplitMenu.Item>
<SplitMenu.Item onSelect={disableStopOnFirstError}>
<Icon type={!stopOnFirstError ? 'check' : ''} fw />
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={disableStopOnFirstError}
trailingIcon={!stopOnFirstError ? 'check' : null}
>
{t('try_to_compile_despite_errors')}
</SplitMenu.Item>
<SplitMenu.Item divider />
<SplitMenu.Item
onSelect={() => stopCompile()}
</DropdownItem>
</li>
<DropdownDivider />
<li role="none">
<DropdownItem
as="button"
onClick={() => stopCompile()}
disabled={!compiling}
aria-disabled={!compiling}
>
{t('stop_compile')}
</SplitMenu.Item>
<SplitMenu.Item
onSelect={fromScratchWithEvent}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={fromScratchWithEvent}
disabled={compiling}
aria-disabled={compiling}
>
{t('recompile_from_scratch')}
</SplitMenu.Item>
</SplitMenu>
}
bs5={
<Dropdown as={OLButtonGroup} className="compile-button-group">
<OLTooltip
description={tooltipElement}
id="compile"
tooltipProps={{ className: 'keyboard-tooltip' }}
overlayProps={{
delay: { show: 500, hide: 0 },
placement: detachRole === 'detached' ? 'bottom' : undefined,
}}
>
<OLButton
variant="primary"
disabled={compiling}
isLoading={compiling}
onClick={() => startCompile()}
className={buttonClassName}
>
{t('recompile')}
</OLButton>
</OLTooltip>
<DropdownToggle
as={DropdownToggleCustom}
split
variant="primary"
id="pdf-recompile-dropdown"
size="sm"
aria-label={t('toggle_compile_options_menu')}
className={dropdownToggleClassName}
/>
<DropdownMenu>
<DropdownHeader>{t('auto_compile')}</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(true, setAutoCompile, 'auto-compile')
}
trailingIcon={autoCompile ? 'check' : null}
>
{t('on')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(false, setAutoCompile, 'auto-compile')
}
trailingIcon={!autoCompile ? 'check' : null}
>
{t('off')}
</DropdownItem>
</li>
<DropdownDivider />
<DropdownHeader>{t('compile_mode')}</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={() => sendEventAndSet(false, setDraft, 'compile-mode')}
trailingIcon={!draft ? 'check' : null}
>
{t('normal')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={() => sendEventAndSet(true, setDraft, 'compile-mode')}
trailingIcon={draft ? 'check' : null}
>
{t('fast')}&nbsp;<span className="subdued">[draft]</span>
</DropdownItem>
</li>
<DropdownDivider />
<DropdownHeader>Syntax Checks</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(
true,
setStopOnValidationError,
'syntax-check'
)
}
trailingIcon={stopOnValidationError ? 'check' : null}
>
{t('stop_on_validation_error')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={() =>
sendEventAndSet(
false,
setStopOnValidationError,
'syntax-check'
)
}
trailingIcon={!stopOnValidationError ? 'check' : null}
>
{t('ignore_validation_errors')}
</DropdownItem>
</li>
<DropdownDivider />
<DropdownHeader>{t('compile_error_handling')}</DropdownHeader>
<li role="none">
<DropdownItem
as="button"
onClick={enableStopOnFirstError}
trailingIcon={stopOnFirstError ? 'check' : null}
>
{t('stop_on_first_error')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={disableStopOnFirstError}
trailingIcon={!stopOnFirstError ? 'check' : null}
>
{t('try_to_compile_despite_errors')}
</DropdownItem>
</li>
<DropdownDivider />
<li role="none">
<DropdownItem
as="button"
onClick={() => stopCompile()}
disabled={!compiling}
aria-disabled={!compiling}
>
{t('stop_compile')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
onClick={fromScratchWithEvent}
disabled={compiling}
aria-disabled={compiling}
>
{t('recompile_from_scratch')}
</DropdownItem>
</li>
</DropdownMenu>
</Dropdown>
}
/>
</DropdownItem>
</li>
</DropdownMenu>
</Dropdown>
)
}
@@ -1,16 +1,12 @@
import { Dropdown as BS3Dropdown } from 'react-bootstrap'
import {
Dropdown,
DropdownMenu,
DropdownToggle,
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import PdfFileList from './pdf-file-list'
import ControlledDropdown from '../../../shared/components/controlled-dropdown'
import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function PdfDownloadFilesButton() {
const { compiling, fileList } = useCompileContext()
@@ -22,41 +18,19 @@ function PdfDownloadFilesButton() {
}
return (
<BootstrapVersionSwitcher
bs3={
<ControlledDropdown
id="dropdown-files-logs-pane"
dropup
pullRight
disabled={compiling || !fileList}
>
<BS3Dropdown.Toggle
className="dropdown-toggle btn-secondary-info btn-secondary"
title={t('other_logs_and_files')}
bsSize="small"
bsStyle={null}
/>
<BS3Dropdown.Menu id="dropdown-files-logs-pane-list">
<PdfFileList fileList={fileList} />
</BS3Dropdown.Menu>
</ControlledDropdown>
}
bs5={
<Dropdown drop="up">
<DropdownToggle
id="dropdown-files-logs-pane"
variant="secondary"
size="sm"
disabled={compiling || !fileList}
>
{t('other_logs_and_files')}
</DropdownToggle>
<DropdownMenu id="dropdown-files-logs-pane-list">
<PdfFileList fileList={fileList} />
</DropdownMenu>
</Dropdown>
}
/>
<Dropdown drop="up">
<DropdownToggle
id="dropdown-files-logs-pane"
variant="secondary"
size="sm"
disabled={compiling || !fileList}
>
{t('other_logs_and_files')}
</DropdownToggle>
<DropdownMenu id="dropdown-files-logs-pane-list">
<PdfFileList fileList={fileList} />
</DropdownMenu>
</Dropdown>
)
}
@@ -1,7 +1,5 @@
import { MenuItem as BS3MenuItem } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
import { memo } from 'react'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import {
DropdownDivider,
DropdownHeader,
@@ -21,94 +19,42 @@ function PdfFileList({ fileList }: { fileList: PdfFileDataList }) {
}
return (
<BootstrapVersionSwitcher
bs3={
<>
<BS3MenuItem header>{t('other_output_files')}</BS3MenuItem>
<>
<DropdownHeader>{t('other_output_files')}</DropdownHeader>
{fileList.top.map(file => (
<BS3MenuItem
download={basename(file)}
href={file.url}
key={file.path}
>
<b>{file.path}</b>
</BS3MenuItem>
))}
{fileList.top.map(file => (
<li key={file.path} role="menuitem">
<DropdownItem role="link" download={basename(file)} href={file.url}>
{file.path}
</DropdownItem>
</li>
))}
{fileList.other.length > 0 && fileList.top.length > 0 && (
<BS3MenuItem divider />
)}
{fileList.other.length > 0 && fileList.top.length > 0 && (
<DropdownDivider />
)}
{fileList.other.map(file => (
<BS3MenuItem
download={basename(file)}
href={file.url}
key={file.path}
>
<b>{file.path}</b>
</BS3MenuItem>
))}
{fileList.other.map(file => (
<li key={file.path} role="menuitem">
<DropdownItem role="link" download={basename(file)} href={file.url}>
{file.path}
</DropdownItem>
</li>
))}
{fileList.archive?.fileCount && fileList.archive?.fileCount > 0 && (
<BS3MenuItem
{fileList.archive?.fileCount !== undefined &&
fileList.archive?.fileCount > 0 && (
<li role="menuitem">
<DropdownItem
role="link"
download={basename(fileList.archive)}
href={fileList.archive.url}
>
<b>
{t('download_all')} ({fileList.archive.fileCount})
</b>
</BS3MenuItem>
)}
</>
}
bs5={
<>
<DropdownHeader>{t('other_output_files')}</DropdownHeader>
{fileList.top.map(file => (
<li key={file.path} role="menuitem">
<DropdownItem
role="link"
download={basename(file)}
href={file.url}
>
{file.path}
</DropdownItem>
</li>
))}
{fileList.other.length > 0 && fileList.top.length > 0 && (
<DropdownDivider />
)}
{fileList.other.map(file => (
<li key={file.path} role="menuitem">
<DropdownItem
role="link"
download={basename(file)}
href={file.url}
>
{file.path}
</DropdownItem>
</li>
))}
{fileList.archive?.fileCount !== undefined &&
fileList.archive?.fileCount > 0 && (
<li role="menuitem">
<DropdownItem
role="link"
download={basename(fileList.archive)}
href={fileList.archive.url}
>
{t('download_all')} ({fileList.archive.fileCount})
</DropdownItem>
</li>
)}
</>
}
/>
{t('download_all')} ({fileList.archive.fileCount})
</DropdownItem>
</li>
)}
</>
)
}
@@ -1,11 +1,8 @@
import { memo, useCallback } from 'react'
import Icon from '../../../shared/components/icon'
import { useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import { bsVersion } from '@/features/utils/bootstrap-5'
function PdfHybridCodeCheckButton() {
const { codeCheckFailed, error, toggleLogs } = useCompileContext()
@@ -27,17 +24,9 @@ function PdfHybridCodeCheckButton() {
disabled={Boolean(error)}
className="btn-toggle-logs toolbar-item"
onClick={handleClick}
bs3Props={{
bsSize: 'xsmall',
}}
>
<BootstrapVersionSwitcher
bs3={<Icon type="exclamation-triangle" />}
bs5={<MaterialIcon type="warning" />}
/>
<span className={bsVersion({ bs3: 'toolbar-text' })}>
{t('code_check_failed')}
</span>
<MaterialIcon type="warning" />
<span className="toolbar-text">{t('code_check_failed')}</span>
</OLButton>
)
}
@@ -2,11 +2,9 @@ import { useTranslation } from 'react-i18next'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import { useProjectContext } from '@/shared/context/project-context'
import { sendMB, isSmallDevice } from '@/infrastructure/event-tracking'
import Icon from '@/shared/components/icon'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import OLButton from '@/features/ui/components/ol/ol-button'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function PdfHybridDownloadButton() {
const { pdfDownloadUrl } = useCompileContext()
@@ -51,10 +49,7 @@ function PdfHybridDownloadButton() {
style={{ pointerEvents: 'auto' }}
aria-label={t('download_pdf')}
>
<BootstrapVersionSwitcher
bs3={<Icon type="download" fw />}
bs5={<MaterialIcon type="download" />}
/>
<MaterialIcon type="download" />
</OLButton>
</OLTooltip>
)
@@ -1,13 +1,11 @@
import { memo, useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import Icon from '@/shared/components/icon'
import MaterialIcon from '@/shared/components/material-icon'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
import * as eventTracking from '@/infrastructure/event-tracking'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import OLButton from '@/features/ui/components/ol/ol-button'
import OLBadge from '@/features/ui/components/ol/ol-badge'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function PdfHybridLogsButton() {
const { error, logEntries, toggleLogs, showLogs, stoppedOnFirstError } =
@@ -42,10 +40,7 @@ function PdfHybridLogsButton() {
style={{ position: 'relative' }}
aria-label={showLogs ? t('view_pdf') : t('view_logs')}
>
<BootstrapVersionSwitcher
bs3={<Icon type="file-text-o" fw />}
bs5={<MaterialIcon type="description" />}
/>
<MaterialIcon type="description" />
{!showLogs && totalCount > 0 && (
<OLBadge bg={errorCount === 0 ? 'warning' : 'danger'}>
@@ -49,10 +49,6 @@ export default function PdfLogEntryRawContent({
<OLButton
variant="secondary"
size="sm"
bs3Props={{
bsSize: 'xsmall',
className: 'log-entry-btn-expand-collapse',
}}
onClick={() => setExpanded(value => !value)}
>
{expanded ? (
@@ -25,7 +25,6 @@ function PdfPreviewError({ error }: { error: string }) {
<OLButton
variant="info"
size="sm"
bs3Props={{ bsSize: 'xsmall' }}
onClick={() => startCompile()}
/>,
]}
@@ -284,7 +283,6 @@ function TimedOutLogEntry() {
<OLButton
variant="info"
size="sm"
bs3Props={{ bsSize: 'xsmall' }}
onClick={handleEnableStopOnFirstErrorClick}
/>,
]}
@@ -9,8 +9,6 @@ import PdfHybridDownloadButton from './pdf-hybrid-download-button'
import PdfHybridCodeCheckButton from './pdf-hybrid-code-check-button'
import PdfOrphanRefreshButton from './pdf-orphan-refresh-button'
import { DetachedSynctexControl } from './detach-synctex-control'
import Icon from '../../../shared/components/icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { Spinner } from 'react-bootstrap-5'
const ORPHAN_UI_TIMEOUT_MS = 5000
@@ -90,16 +88,11 @@ function PdfPreviewHybridToolbarConnectingInner() {
return (
<>
<div className="toolbar-pdf-orphan">
<BootstrapVersionSwitcher
bs3={<Icon type="refresh" fw spin />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
&nbsp;
{t('tab_connecting')}
@@ -5,7 +5,6 @@ import { getJSON } from '../../../infrastructure/fetch-json'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import { useLayoutContext } from '../../../shared/context/layout-context'
import useScopeValue from '../../../shared/hooks/use-scope-value'
import Icon from '../../../shared/components/icon'
import { useTranslation } from 'react-i18next'
import useIsMounted from '../../../shared/hooks/use-is-mounted'
import useAbortController from '../../../shared/hooks/use-abort-controller'
@@ -19,10 +18,8 @@ import { debugConsole } from '@/utils/debugging'
import { useFileTreePathContext } from '@/features/file-tree/contexts/file-tree-path'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import { Spinner } from 'react-bootstrap-5'
import { bsVersion } from '@/features/utils/bootstrap-5'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
import useEventListener from '@/shared/hooks/use-event-listener'
import { PdfScrollPosition } from '@/shared/hooks/use-pdf-scroll-position'
@@ -49,29 +46,11 @@ function GoToCodeButton({
let buttonIcon = null
if (syncToCodeInFlight) {
buttonIcon = (
<BootstrapVersionSwitcher
bs3={<Icon type="refresh" spin className="synctex-spin-icon" />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
/>
<Spinner animation="border" aria-hidden="true" size="sm" role="status" />
)
} else if (!isDetachLayout) {
buttonIcon = (
<BootstrapVersionSwitcher
bs3={<Icon type="arrow-left" className="synctex-control-icon" />}
bs5={
<MaterialIcon
type="arrow_left_alt"
className="synctex-control-icon"
/>
}
/>
<MaterialIcon type="arrow_left_alt" className="synctex-control-icon" />
)
}
@@ -96,9 +75,6 @@ function GoToCodeButton({
disabled={syncToCodeInFlight}
className={buttonClasses}
aria-label={t('go_to_pdf_location_in_code')}
bs3Props={{
bsSize: 'xsmall',
}}
>
{buttonIcon}
{isDetachLayout ? <span>&nbsp;{t('show_in_code')}</span> : ''}
@@ -122,40 +98,18 @@ function GoToPdfButton({
}) {
const { t } = useTranslation()
const tooltipPlacement = isDetachLayout ? 'bottom' : 'right'
const buttonClasses = classNames(
'synctex-control',
bsVersion({ bs3: 'toolbar-btn-secondary' }),
{
'detach-synctex-control': !!isDetachLayout,
}
)
const buttonClasses = classNames('synctex-control', {
'detach-synctex-control': !!isDetachLayout,
})
let buttonIcon = null
if (syncToPdfInFlight) {
buttonIcon = (
<BootstrapVersionSwitcher
bs3={<Icon type="refresh" spin className="synctex-spin-icon" />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
/>
<Spinner animation="border" aria-hidden="true" size="sm" role="status" />
)
} else if (!isDetachLayout) {
buttonIcon = (
<BootstrapVersionSwitcher
bs3={<Icon type="arrow-right" className="synctex-control-icon" />}
bs5={
<MaterialIcon
type="arrow_right_alt"
className="synctex-control-icon"
/>
}
/>
<MaterialIcon type="arrow_right_alt" className="synctex-control-icon" />
)
}
@@ -172,9 +126,6 @@ function GoToPdfButton({
disabled={syncToPdfInFlight || !canSyncToPdf}
className={buttonClasses}
aria-label={t('go_to_code_location_in_pdf')}
bs3Props={{
bsSize: 'xsmall',
}}
>
{buttonIcon}
{isDetachLayout ? <span>&nbsp;{t('show_in_pdf')}</span> : ''}
@@ -1,9 +1,6 @@
import { Dropdown as BS3Dropdown, MenuItem } from 'react-bootstrap'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import ControlledDropdown from '@/shared/components/controlled-dropdown'
import classNames from 'classnames'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import {
Dropdown,
DropdownDivider,
@@ -59,215 +56,117 @@ function PdfZoomDropdown({
const showPresentOption = document.fullscreenEnabled
return (
<BootstrapVersionSwitcher
bs3={
<ControlledDropdown
id="pdf-zoom-dropdown"
onSelect={eventKey => {
if (eventKey === 'custom-zoom') {
return
}
<Dropdown
onSelect={eventKey => {
if (eventKey === 'custom-zoom') {
return
}
if (eventKey === 'present') {
requestPresentationMode()
return
}
if (eventKey === 'present') {
requestPresentationMode()
return
}
setZoom(eventKey)
}}
pullRight
>
<BS3Dropdown.Toggle
bsStyle={null}
className="btn pdf-toolbar-btn pdfjs-zoom-dropdown-button small"
value={rawScale}
title={rawScaleToPercentage(rawScale)}
/>
<BS3Dropdown.Menu className="pdfjs-zoom-dropdown-menu">
<MenuItem
draggable={false}
disabled
className="pdfjs-custom-zoom-menu-item"
key="custom-zoom"
eventKey="custom-zoom"
>
<input
type="text"
onFocus={event => event.target.select()}
value={customZoomValue}
onKeyDown={event => {
if (event.key === 'Enter') {
const zoom = Number(customZoomValue.replace('%', '')) / 100
// Only allow zoom values between 10% and 999%
if (zoom < 0.1) {
setZoom('0.1')
} else if (zoom > 9.99) {
setZoom('9.99')
} else {
setZoom(`${zoom}`)
}
}
}}
onChange={event => {
const rawValue = event.target.value
const parsedValue = rawValue.replace(/[^0-9%]/g, '')
setCustomZoomValue(parsedValue)
}}
/>
</MenuItem>
<MenuItem divider />
<MenuItem draggable={false} key="zoom-in" eventKey="zoom-in">
<span>{t('zoom_in')}</span>
<Shortcut keys={shortcuts['zoom-in']} />
</MenuItem>
<MenuItem draggable={false} key="zoom-out" eventKey="zoom-out">
<span>{t('zoom_out')}</span>
<Shortcut keys={shortcuts['zoom-out']} />
</MenuItem>
<MenuItem draggable={false} key="page-width" eventKey="page-width">
{t('fit_to_width')}
<Shortcut keys={shortcuts['fit-to-width']} />
</MenuItem>
<MenuItem
draggable={false}
key="page-height"
eventKey="page-height"
>
{t('fit_to_height')}
<Shortcut keys={shortcuts['fit-to-height']} />
</MenuItem>
{showPresentOption && <MenuItem divider />}
{showPresentOption && (
<MenuItem draggable={false} key="present" eventKey="present">
{t('presentation_mode')}
</MenuItem>
)}
<MenuItem divider />
<MenuItem header>{t('zoom_to')}</MenuItem>
{zoomValues.map(value => (
<MenuItem draggable={false} key={value} eventKey={value}>
{rawScaleToPercentage(Number(value))}
</MenuItem>
))}
</BS3Dropdown.Menu>
</ControlledDropdown>
}
bs5={
<Dropdown
onSelect={eventKey => {
if (eventKey === 'custom-zoom') {
return
}
if (eventKey === 'present') {
requestPresentationMode()
return
}
setZoom(eventKey)
}}
align="end"
>
<DropdownToggle
id="pdf-zoom-dropdown"
variant="link"
className="pdf-toolbar-btn pdfjs-zoom-dropdown-button small"
setZoom(eventKey)
}}
align="end"
>
<DropdownToggle
id="pdf-zoom-dropdown"
variant="link"
className="pdf-toolbar-btn pdfjs-zoom-dropdown-button small"
>
{rawScaleToPercentage(rawScale)}
</DropdownToggle>
<DropdownMenu className="pdfjs-zoom-dropdown-menu">
<li role="none">
<DropdownItem
disabled
as="div"
className="pdfjs-custom-zoom-menu-item"
eventKey="custom-zoom"
>
{rawScaleToPercentage(rawScale)}
</DropdownToggle>
<DropdownMenu className="pdfjs-zoom-dropdown-menu">
<li role="none">
<DropdownItem
disabled
as="div"
className="pdfjs-custom-zoom-menu-item"
eventKey="custom-zoom"
>
<FormControl
onFocus={event => event.target.select()}
value={customZoomValue}
onKeyDown={event => {
if (event.key === 'Enter') {
const zoom =
Number(customZoomValue.replace('%', '')) / 100
<FormControl
onFocus={event => event.target.select()}
value={customZoomValue}
onKeyDown={event => {
if (event.key === 'Enter') {
const zoom = Number(customZoomValue.replace('%', '')) / 100
// Only allow zoom values between 10% and 999%
if (zoom < 0.1) {
setZoom('0.1')
} else if (zoom > 9.99) {
setZoom('9.99')
} else {
setZoom(`${zoom}`)
}
}
}}
onChange={event => {
const rawValue = event.target.value
const parsedValue = rawValue.replace(/[^0-9%]/g, '')
setCustomZoomValue(parsedValue)
}}
/>
</DropdownItem>
</li>
<DropdownDivider />
<li role="none">
<DropdownItem
as="button"
eventKey="zoom-in"
trailingIcon={<Shortcut keys={shortcuts['zoom-in']} />}
>
{t('zoom_in')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
eventKey="zoom-out"
trailingIcon={<Shortcut keys={shortcuts['zoom-out']} />}
>
{t('zoom_out')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
eventKey="page-width"
trailingIcon={<Shortcut keys={shortcuts['fit-to-width']} />}
>
{t('fit_to_width')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
eventKey="page-height"
trailingIcon={<Shortcut keys={shortcuts['fit-to-height']} />}
>
{t('fit_to_height')}
</DropdownItem>
</li>
{showPresentOption && <DropdownDivider />}
{showPresentOption && (
<li role="none">
<DropdownItem as="button" eventKey="present">
{t('presentation_mode')}
</DropdownItem>
</li>
)}
<DropdownDivider />
<DropdownHeader aria-hidden="true">{t('zoom_to')}</DropdownHeader>
{zoomValues.map(value => (
<li role="none" key={value}>
<DropdownItem as="button" eventKey={value}>
{rawScaleToPercentage(Number(value))}
</DropdownItem>
</li>
))}
</DropdownMenu>
</Dropdown>
}
/>
// Only allow zoom values between 10% and 999%
if (zoom < 0.1) {
setZoom('0.1')
} else if (zoom > 9.99) {
setZoom('9.99')
} else {
setZoom(`${zoom}`)
}
}
}}
onChange={event => {
const rawValue = event.target.value
const parsedValue = rawValue.replace(/[^0-9%]/g, '')
setCustomZoomValue(parsedValue)
}}
/>
</DropdownItem>
</li>
<DropdownDivider />
<li role="none">
<DropdownItem
as="button"
eventKey="zoom-in"
trailingIcon={<Shortcut keys={shortcuts['zoom-in']} />}
>
{t('zoom_in')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
eventKey="zoom-out"
trailingIcon={<Shortcut keys={shortcuts['zoom-out']} />}
>
{t('zoom_out')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
eventKey="page-width"
trailingIcon={<Shortcut keys={shortcuts['fit-to-width']} />}
>
{t('fit_to_width')}
</DropdownItem>
</li>
<li role="none">
<DropdownItem
as="button"
eventKey="page-height"
trailingIcon={<Shortcut keys={shortcuts['fit-to-height']} />}
>
{t('fit_to_height')}
</DropdownItem>
</li>
{showPresentOption && <DropdownDivider />}
{showPresentOption && (
<li role="none">
<DropdownItem as="button" eventKey="present">
{t('presentation_mode')}
</DropdownItem>
</li>
)}
<DropdownDivider />
<DropdownHeader aria-hidden="true">{t('zoom_to')}</DropdownHeader>
{zoomValues.map(value => (
<li role="none" key={value}>
<DropdownItem as="button" eventKey={value}>
{rawScaleToPercentage(Number(value))}
</DropdownItem>
</li>
))}
</DropdownMenu>
</Dropdown>
)
}
@@ -28,12 +28,7 @@ export default function StopOnFirstErrorPrompt() {
// eslint-disable-next-line react/jsx-key
components={[<strong />]}
/>{' '}
<OLButton
variant="info"
size="sm"
onClick={handleDisableButtonClick}
bs3Props={{ bsSize: 'xsmall' }}
>
<OLButton variant="info" size="sm" onClick={handleDisableButtonClick}>
{t('disable_stop_on_first_error')}
</OLButton>
</>
@@ -1,8 +1,6 @@
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import MaterialIcon from '@/shared/components/material-icon'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { useLayoutContext } from '../../../shared/context/layout-context'
function SwitchToEditorButton() {
@@ -26,19 +24,8 @@ function SwitchToEditorButton() {
}
return (
<OLButton
variant="secondary"
size="sm"
onClick={handleClick}
bs3Props={{
bsSize: 'xsmall',
className: 'switch-to-editor-btn toolbar-btn-secondary',
}}
>
<BootstrapVersionSwitcher
bs3={<Icon type="code" className="toolbar-btn-secondary-icon" />}
bs5={<MaterialIcon type="code" />}
/>
<OLButton variant="secondary" size="sm" onClick={handleClick}>
<MaterialIcon type="code" />
{t('switch_to_editor')}
</OLButton>
)
@@ -177,7 +177,6 @@ const PreventTimeoutHelpMessage = memo(function PreventTimeoutHelpMessage({
className="btn-inline-link fw-bold"
size="sm"
onClick={handleEnableStopOnFirstErrorClick}
bs3Props={{ bsSize: 'xsmall' }}
/>,
// eslint-disable-next-line react/jsx-key
<strong />,
@@ -3,9 +3,7 @@ import { useState, useRef, MouseEventHandler } from 'react'
import { useTranslation } from 'react-i18next'
import useResizeObserver from '../hooks/use-resize-observer'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import Icon from '../../../shared/components/icon'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import { ErrorLevel, SourceLocation } from '@/features/pdf-preview/util/types'
@@ -91,15 +89,7 @@ function PreviewLogEntryHeader({
aria-label={headerLogLocationTitle}
onClick={onSourceLocationClick}
>
<BootstrapVersionSwitcher
bs3={
<>
<Icon type="chain" />
&nbsp;
</>
}
bs5={<MaterialIcon type="link" />}
/>
<MaterialIcon type="link" />
<span ref={logLocationSpanRef} className="log-entry-header-link-location">
{`\u202A${locationLinkText}\u202C`}
</span>
@@ -3,11 +3,9 @@ import PropTypes from 'prop-types'
import { Trans, useTranslation } from 'react-i18next'
import OLButton from '@/features/ui/components/ol/ol-button'
import PreviewLogEntryHeader from './preview-log-entry-header'
import Icon from '../../../shared/components/icon'
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
const { t } = useTranslation()
@@ -36,12 +34,7 @@ function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
{hasErrors && !stoppedOnFirstError ? (
<>
<p>
<BootstrapVersionSwitcher
bs3={<Icon type="lightbulb-o" />}
bs5={
<MaterialIcon type="lightbulb" className="align-middle" />
}
/>
<MaterialIcon type="lightbulb" className="align-middle" />
&nbsp;
<strong>{t('tip')}: </strong>
<Trans
@@ -51,7 +44,6 @@ function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
variant="info"
size="sm"
key="enable-stop-on-first-error"
bs3Props={{ bsSize: 'xsmall' }}
onClick={handleEnableStopOnFirstErrorClick}
/>,
// eslint-disable-next-line jsx-a11y/anchor-has-content
@@ -66,10 +58,7 @@ function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
</>
) : (
<p>
<BootstrapVersionSwitcher
bs3={<Icon type="lightbulb-o" />}
bs5={<MaterialIcon type="lightbulb" className="align-middle" />}
/>
<MaterialIcon type="lightbulb" className="align-middle" />
&nbsp;
<strong>{t('tip')}: </strong>
{t('log_entry_maximum_entries_see_full_logs')}
@@ -1,12 +1,6 @@
import ControlledDropdown from '@/shared/components/controlled-dropdown'
import MaterialIcon from '@/shared/components/material-icon'
import { FC, memo, forwardRef } from 'react'
import {
Dropdown as BS3Dropdown,
MenuItem as BS3MenuItem,
} from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import {
Dropdown,
DropdownItem,
@@ -38,61 +32,35 @@ const ReviewPanelCommentOptions: FC<{
}
return (
<BootstrapVersionSwitcher
bs3={
<ControlledDropdown id={`review-panel-comment-options-${id}`} pullRight>
<BS3Dropdown.Toggle
tabIndex={0}
noCaret
bsSize="small"
bsStyle={null}
>
<MaterialIcon
type="more_vert"
className="review-panel-entry-actions-icon"
accessibilityLabel={t('more_options')}
/>
</BS3Dropdown.Toggle>
<BS3Dropdown.Menu>
{canEdit && <BS3MenuItem onClick={onEdit}>{t('edit')}</BS3MenuItem>}
{canDelete && (
<BS3MenuItem onClick={onDelete}>{t('delete')}</BS3MenuItem>
)}
</BS3Dropdown.Menu>
</ControlledDropdown>
}
bs5={
<Dropdown align="end">
<DropdownToggle
tabIndex={0}
as={ReviewPanelCommentDropdownToggleButton}
id={`review-panel-comment-options-btn-${id}`}
>
<MaterialIcon
type="more_vert"
className="review-panel-entry-actions-icon"
accessibilityLabel={t('more_options')}
/>
</DropdownToggle>
<DropdownMenu flip={false}>
{canEdit && (
<li role="none">
<DropdownItem as="button" onClick={onEdit}>
{t('edit')}
</DropdownItem>
</li>
)}
{canDelete && (
<li role="none">
<DropdownItem as="button" onClick={onDelete}>
{t('delete')}
</DropdownItem>
</li>
)}
</DropdownMenu>
</Dropdown>
}
/>
<Dropdown align="end">
<DropdownToggle
tabIndex={0}
as={ReviewPanelCommentDropdownToggleButton}
id={`review-panel-comment-options-btn-${id}`}
>
<MaterialIcon
type="more_vert"
className="review-panel-entry-actions-icon"
accessibilityLabel={t('more_options')}
/>
</DropdownToggle>
<DropdownMenu flip={false}>
{canEdit && (
<li role="none">
<DropdownItem as="button" onClick={onEdit}>
{t('edit')}
</DropdownItem>
</li>
)}
{canDelete && (
<li role="none">
<DropdownItem as="button" onClick={onDelete}>
{t('delete')}
</DropdownItem>
</li>
)}
</DropdownMenu>
</Dropdown>
)
}
@@ -3,7 +3,6 @@ import MaterialIcon from '@/shared/components/material-icon'
import classNames from 'classnames'
import { useTranslation } from 'react-i18next'
import OLButton from '@/features/ui/components/ol/ol-button'
import { bsVersion } from '@/features/utils/bootstrap-5'
const MoreCommentsButton: FC<{
onClick: () => void
@@ -18,15 +17,7 @@ const MoreCommentsButton: FC<{
upwards: direction === 'upward',
})}
>
<OLButton
variant="secondary"
size="sm"
className={bsVersion({ bs3: 'review-panel-more-comments-button' })}
onClick={onClick}
bs3Props={{
bsSize: 'xsmall',
}}
>
<OLButton variant="secondary" size="sm" onClick={onClick}>
<MaterialIcon type={`arrow_${direction}_alt`} />
{t('more_comments')}
</OLButton>
@@ -1,11 +1,9 @@
import React, { FC, useRef, useState } from 'react'
import Icon from '@/shared/components/icon'
import OLOverlay from '@/features/ui/components/ol/ol-overlay'
import OLPopover from '@/features/ui/components/ol/ol-popover'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import { ReviewPanelResolvedThreadsMenu } from './review-panel-resolved-threads-menu'
import { useTranslation } from 'react-i18next'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import getMeta from '@/utils/meta'
@@ -30,10 +28,7 @@ export const ReviewPanelResolvedThreadsButton: FC = () => {
ref={buttonRef}
onClick={() => setExpanded(true)}
>
<BootstrapVersionSwitcher
bs3={<Icon type="inbox" fw />}
bs5={<MaterialIcon type="inbox" />}
/>
<MaterialIcon type="inbox" />
</button>
</OLTooltip>
{expanded && (
@@ -1,8 +1,6 @@
import { FC, memo, useState } from 'react'
import { Trans } from 'react-i18next'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
import Icon from '@/shared/components/icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import { useProjectContext } from '@/shared/context/project-context'
import UpgradeTrackChangesModal from '@/features/source-editor/components/review-panel/upgrade-track-changes-modal'
@@ -51,14 +49,7 @@ const ReviewPanelTrackChangesMenuButton: FC<{
components={{ strong: <strong /> }}
/>
)}
<BootstrapVersionSwitcher
bs3={<Icon type={menuExpanded ? 'angle-down' : 'angle-right'} />}
bs5={
<MaterialIcon
type={menuExpanded ? 'expand_more' : 'chevron_right'}
/>
}
/>
<MaterialIcon type={menuExpanded ? 'expand_more' : 'chevron_right'} />
</button>
<UpgradeTrackChangesModal show={showModal} setShow={setShowModal} />
@@ -166,9 +166,6 @@ export default function AddCollaborators({ readOnly }) {
className="privileges"
value={privileges}
onChange={event => setPrivileges(event.target.value)}
bs3Props={{
bsSize: 'sm',
}}
>
<option disabled={readOnly} value="readAndWrite">
{t('can_edit')}
@@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next'
import { useShareProjectContext } from './share-project-modal'
import TransferOwnershipModal from './transfer-ownership-modal'
import { removeMemberFromProject, updateMember } from '../utils/api'
import Icon from '@/shared/components/icon'
import { useProjectContext } from '@/shared/context/project-context'
import { sendMB } from '@/infrastructure/event-tracking'
import { Select } from '@/shared/components/select'
@@ -15,9 +14,6 @@ import OLButton from '@/features/ui/components/ol/ol-button'
import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
import OLCol from '@/features/ui/components/ol/ol-col'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { bsVersion } from '@/features/utils/bootstrap-5'
import classnames from 'classnames'
import getMeta from '@/utils/meta'
import { useUserContext } from '@/shared/context/user-context'
@@ -135,7 +131,6 @@ export default function EditMember({
return (
<form
className={bsVersion({ bs3: 'form-horizontal' })}
id="share-project-form"
onSubmit={e => {
e.preventDefault()
@@ -144,35 +139,19 @@ export default function EditMember({
}
}}
>
<OLFormGroup
className={classnames('project-member', bsVersion({ bs5: 'row' }))}
>
<OLFormGroup className="project-member row">
<OLCol xs={7}>
<div className="project-member-email-icon">
<BootstrapVersionSwitcher
bs3={
<Icon
type={
shouldWarnMember() || member.pendingEditor
? 'warning'
: 'user'
}
fw
/>
<MaterialIcon
type={
shouldWarnMember() || member.pendingEditor
? 'warning'
: 'person'
}
bs5={
<MaterialIcon
type={
shouldWarnMember() || member.pendingEditor
? 'warning'
: 'person'
}
className={
shouldWarnMember() || member.pendingEditor
? 'project-member-warning'
: undefined
}
/>
className={
shouldWarnMember() || member.pendingEditor
? 'project-member-warning'
: undefined
}
/>
<div className="email-warning">
@@ -200,15 +179,7 @@ export default function EditMember({
<div className="project-member-select">
{hasBeenDowngraded && !confirmRemoval && (
<BootstrapVersionSwitcher
bs3={<Icon type="warning" fw />}
bs5={
<MaterialIcon
type="warning"
className="project-member-warning"
/>
}
/>
<MaterialIcon type="warning" className="project-member-warning" />
)}
<SelectPrivilege
@@ -1,7 +1,6 @@
import { useCallback } from 'react'
import PropTypes from 'prop-types'
import { useShareProjectContext } from './share-project-modal'
import Icon from '@/shared/components/icon'
import { useTranslation } from 'react-i18next'
import MemberPrivileges from './member-privileges'
import { resendInvite, revokeInvite } from '../utils/api'
@@ -12,9 +11,6 @@ import OLCol from '@/features/ui/components/ol/ol-col'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import OLButton from '@/features/ui/components/ol/ol-button'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { bsVersion } from '@/features/utils/bootstrap-5'
import classnames from 'classnames'
export default function Invite({ invite, isProjectOwner }) {
const { t } = useTranslation()
@@ -123,15 +119,9 @@ function RevokeInvite({ invite }) {
variant="link"
onClick={handleClick}
aria-label={t('revoke')}
className={classnames(
'btn-inline-link',
bsVersion({ bs5: 'text-decoration-none' })
)}
className="btn-inline-link text-decoration-none"
>
<BootstrapVersionSwitcher
bs3={<Icon type="times" />}
bs5={<MaterialIcon type="clear" />}
/>
<MaterialIcon type="clear" />
</OLButton>
</OLTooltip>
)
@@ -1,7 +1,6 @@
import { useCallback, useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import Icon from '@/shared/components/icon'
import { useShareProjectContext } from './share-project-modal'
import { setProjectAccessLevel } from '../utils/api'
import { CopyToClipboard } from '@/shared/components/copy-to-clipboard'
@@ -17,7 +16,6 @@ import OLRow from '@/features/ui/components/ol/ol-row'
import OLCol from '@/features/ui/components/ol/ol-col'
import OLButton from '@/features/ui/components/ol/ol-button'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export default function LinkSharing() {
@@ -161,13 +159,8 @@ function TokenBasedSharing({
className="btn-chevron align-middle"
onClick={() => setShowLinks(!showLinks)}
>
<BootstrapVersionSwitcher
bs3={<Icon type={showLinks ? 'chevron-up' : 'chevron-down'} fw />}
bs5={
<MaterialIcon
type={showLinks ? 'keyboard_arrow_up' : 'keyboard_arrow_down'}
/>
}
<MaterialIcon
type={showLinks ? 'keyboard_arrow_up' : 'keyboard_arrow_down'}
/>
</OLButton>
</OLCol>
@@ -315,10 +308,7 @@ function LinkSharingInfo() {
target="_blank"
rel="noopener"
>
<BootstrapVersionSwitcher
bs3={<Icon type="question-circle" />}
bs5={<MaterialIcon type="help" className="align-middle" />}
/>
<MaterialIcon type="help" className="align-middle" />
</a>
</OLTooltip>
)
@@ -1,9 +1,7 @@
import { useProjectContext } from '@/shared/context/project-context'
import { useTranslation } from 'react-i18next'
import Icon from '@/shared/components/icon'
import OLRow from '@/features/ui/components/ol/ol-row'
import OLCol from '@/features/ui/components/ol/ol-col'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export default function OwnerInfo() {
@@ -14,10 +12,7 @@ export default function OwnerInfo() {
<OLRow className="project-member">
<OLCol xs={8}>
<div className="project-member-email-icon">
<BootstrapVersionSwitcher
bs3={<Icon type="user" fw />}
bs5={<MaterialIcon type="person" />}
/>
<MaterialIcon type="person" />
<div className="email-warning">{owner?.email}</div>
</div>
</OLCol>
@@ -5,12 +5,9 @@ import { matchSorter } from 'match-sorter'
import { useCombobox } from 'downshift'
import classnames from 'classnames'
import Icon from '@/shared/components/icon'
import MaterialIcon from '@/shared/components/material-icon'
import Tag from '@/features/ui/components/bootstrap-5/tag'
import { DropdownItem } from '@/features/ui/components/bootstrap-5/dropdown-menu'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { bsVersion } from '@/features/utils/bootstrap-5'
import { Spinner } from 'react-bootstrap-5'
// Unicode characters in these Unicode groups:
@@ -163,16 +160,11 @@ export default function SelectCollaborators({
&nbsp;
</strong>
{loading && (
<BootstrapVersionSwitcher
bs3={<Icon type="refresh" spin />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
)}
</label>
@@ -265,19 +257,12 @@ export default function SelectCollaborators({
/>
</div>
<div
className={bsVersion({ bs3: classnames({ autocomplete: isOpen }) })}
>
<div>
<ul
{...getMenuProps()}
className={classnames(
bsVersion({
bs3: 'suggestion-list',
bs5: classnames('dropdown-menu select-dropdown-menu', {
show: isOpen,
}),
})
)}
className={classnames('dropdown-menu select-dropdown-menu', {
show: isOpen,
})}
>
{isOpen &&
filteredOptions.map((item, index) => (
@@ -310,33 +295,17 @@ SelectCollaborators.propTypes = {
function Option({ selected, item, getItemProps, index }) {
return (
<li
className={bsVersion({
bs3: classnames('suggestion-item', { selected }),
})}
{...getItemProps({ item, index })}
>
<BootstrapVersionSwitcher
bs3={
<>
<Icon type="user" fw />
&nbsp;
{item.display}
</>
}
bs5={
<DropdownItem
as="span"
role={undefined}
leadingIcon="person"
className={classnames({
active: selected,
})}
>
{item.display}
</DropdownItem>
}
/>
<li {...getItemProps({ item, index })}>
<DropdownItem
as="span"
role={undefined}
leadingIcon="person"
className={classnames({
active: selected,
})}
>
{item.display}
</DropdownItem>
</li>
)
}
@@ -357,8 +326,6 @@ function SelectedItem({
getSelectedItemProps,
index,
}) {
const { t } = useTranslation()
const handleClick = useCallback(
event => {
event.preventDefault()
@@ -370,41 +337,15 @@ function SelectedItem({
)
return (
<BootstrapVersionSwitcher
bs3={
<span
className="tag-item"
{...getSelectedItemProps({ selectedItem, index })}
>
<Icon type="user" fw />
<span>{selectedItem.display}</span>
<button
type="button"
className="remove-button btn-inline-link"
aria-label={t('remove')}
onClick={handleClick}
>
<Icon type="close" fw />
</button>
</span>
}
bs5={
<Tag
prepend={
<BootstrapVersionSwitcher
bs3={<Icon type="user" fw />}
bs5={<MaterialIcon type="person" />}
/>
}
closeBtnProps={{
onClick: handleClick,
}}
{...getSelectedItemProps({ selectedItem, index })}
>
{selectedItem.display}
</Tag>
}
/>
<Tag
prepend={<MaterialIcon type="person" />}
closeBtnProps={{
onClick: handleClick,
}}
{...getSelectedItemProps({ selectedItem, index })}
>
{selectedItem.display}
</Tag>
)
}
@@ -1,5 +1,4 @@
import { useTranslation } from 'react-i18next'
import Icon from '@/shared/components/icon'
import { useEditorContext } from '@/shared/context/editor-context'
import { lazy, Suspense } from 'react'
import { FullSizeLoadingSpinner } from '@/shared/components/loading-spinner'
@@ -12,8 +11,6 @@ import OLModal, {
} from '@/features/ui/components/ol/ol-modal'
import OLNotification from '@/features/ui/components/ol/ol-notification'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { bsVersion } from '@/features/utils/bootstrap-5'
import { Spinner } from 'react-bootstrap-5'
const ReadOnlyTokenLink = lazy(() =>
@@ -70,18 +67,13 @@ export default function ShareProjectModalContent({
</OLModalBody>
<OLModalFooter>
<div className={bsVersion({ bs3: 'pull-left', bs5: 'me-auto' })}>
<div className="me-auto">
{inFlight && (
<BootstrapVersionSwitcher
bs3={<Icon type="refresh" spin />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
)}
</div>
@@ -1,7 +1,6 @@
import { useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import PropTypes from 'prop-types'
import Icon from '@/shared/components/icon'
import { transferProjectOwnership } from '../utils/api'
import { useProjectContext } from '@/shared/context/project-context'
import { useLocation } from '@/shared/hooks/use-location'
@@ -13,8 +12,6 @@ import OLModal, {
} from '@/features/ui/components/ol/ol-modal'
import OLNotification from '@/features/ui/components/ol/ol-notification'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import { bsVersion } from '@/features/utils/bootstrap-5'
import { Spinner } from 'react-bootstrap-5'
export default function TransferOwnershipModal({ member, cancel }) {
@@ -65,18 +62,13 @@ export default function TransferOwnershipModal({ member, cancel }) {
)}
</OLModalBody>
<OLModalFooter>
<div className={bsVersion({ bs3: 'pull-left', bs5: 'me-auto' })}>
<div className="me-auto">
{inflight && (
<BootstrapVersionSwitcher
bs3={<Icon type="refresh" spin />}
bs5={
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
}
<Spinner
animation="border"
aria-hidden="true"
size="sm"
role="status"
/>
)}
</div>
@@ -1,20 +1,15 @@
import PropTypes from 'prop-types'
import MemberPrivileges from './member-privileges'
import Icon from '@/shared/components/icon'
import OLRow from '@/features/ui/components/ol/ol-row'
import OLCol from '@/features/ui/components/ol/ol-col'
import MaterialIcon from '@/shared/components/material-icon'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
export default function ViewMember({ member }) {
return (
<OLRow className="project-member">
<OLCol xs={8}>
<div className="project-member-email-icon">
<BootstrapVersionSwitcher
bs3={<Icon type="user" fw />}
bs5={<MaterialIcon type="person" />}
/>
<MaterialIcon type="person" />
<div className="email-warning">{member.email}</div>
</div>
</OLCol>
@@ -17,13 +17,11 @@ import {
} from '@codemirror/search'
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import OLButtonGroup from '@/features/ui/components/ol/ol-button-group'
import OLFormControl from '@/features/ui/components/ol/ol-form-control'
import OLCloseButton from '@/features/ui/components/ol/ol-close-button'
import { useTranslation } from 'react-i18next'
import Icon from '../../../shared/components/icon'
import classnames from 'classnames'
import { useUserSettingsContext } from '@/shared/context/user-settings-context'
import { getStoredSelection, setStoredSelection } from '../extensions/search'
@@ -328,10 +326,7 @@ const CodeMirrorSearchForm: FC = () => {
htmlFor={withinSelectionId}
aria-label={t('search_within_selection')}
>
<BootstrapVersionSwitcher
bs3={<Icon type="align-left" fw />}
bs5={<MaterialIcon type="format_align_left" />}
/>
<MaterialIcon type="format_align_left" />
</label>
</OLTooltip>
</span>
@@ -411,20 +406,9 @@ const CodeMirrorSearchForm: FC = () => {
size="sm"
onClick={() => findPrevious(view)}
>
<BootstrapVersionSwitcher
bs3={
<Icon
type="chevron-up"
fw
accessibilityLabel={t('search_previous')}
/>
}
bs5={
<MaterialIcon
type="keyboard_arrow_up"
accessibilityLabel={t('search_previous')}
/>
}
<MaterialIcon
type="keyboard_arrow_up"
accessibilityLabel={t('search_previous')}
/>
</OLButton>
@@ -433,20 +417,9 @@ const CodeMirrorSearchForm: FC = () => {
size="sm"
onClick={() => findNext(view)}
>
<BootstrapVersionSwitcher
bs3={
<Icon
type="chevron-down"
fw
accessibilityLabel={t('search_next')}
/>
}
bs5={
<MaterialIcon
type="keyboard_arrow_down"
accessibilityLabel={t('search_next')}
/>
}
<MaterialIcon
type="keyboard_arrow_down"
accessibilityLabel={t('search_next')}
/>
</OLButton>
</OLButtonGroup>
@@ -14,7 +14,6 @@ import {
ShortTextArgument,
UrlArgument,
} from '../../lezer-latex/latex.terms.mjs'
import Icon from '../../../../shared/components/icon'
import { EditorState } from '@codemirror/state'
import { openURL } from '@/features/source-editor/utils/url'
import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
@@ -22,7 +21,6 @@ import OLFormLabel from '@/features/ui/components/ol/ol-form-label'
import OLFormControl from '@/features/ui/components/ol/ol-form-control'
import OLForm from '@/features/ui/components/ol/ol-form'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export const HrefTooltipContent: FC = () => {
@@ -118,10 +116,7 @@ export const HrefTooltipContent: FC = () => {
openURL(url)
}}
>
<BootstrapVersionSwitcher
bs3={<Icon type="external-link" fw />}
bs5={<MaterialIcon type="open_in_new" />}
/>
<MaterialIcon type="open_in_new" />
{t('open_link')}
</OLButton>
@@ -139,10 +134,7 @@ export const HrefTooltipContent: FC = () => {
}
}}
>
<BootstrapVersionSwitcher
bs3={<Icon type="chain-broken" fw />}
bs5={<MaterialIcon type="link_off" />}
/>
<MaterialIcon type="link_off" />
{t('remove_link')}
</OLButton>
@@ -1,8 +1,6 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Icon from '@/shared/components/icon'
import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import OLButton from '@/features/ui/components/ol/ol-button'
@@ -18,10 +16,7 @@ export const IncludeTooltipContent: FC = () => {
className="ol-cm-command-tooltip-link"
onClick={openIncludedFile}
>
<BootstrapVersionSwitcher
bs3={<Icon type="edit" fw />}
bs5={<MaterialIcon type="edit" />}
/>
<MaterialIcon type="edit" />
{t('open_file')}
</OLButton>
</div>
@@ -1,9 +1,7 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Icon from '@/shared/components/icon'
import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export const InputTooltipContent: FC = () => {
@@ -18,10 +16,7 @@ export const InputTooltipContent: FC = () => {
className="ol-cm-command-tooltip-link"
onClick={openIncludedFile}
>
<BootstrapVersionSwitcher
bs3={<Icon type="edit" fw />}
bs5={<MaterialIcon type="edit" />}
/>
<MaterialIcon type="edit" />
{t('open_file')}
</OLButton>
</div>
@@ -19,9 +19,7 @@ import {
TransactionSpec,
} from '@codemirror/state'
import { EditorView } from '@codemirror/view'
import Icon from '../../../../shared/components/icon'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export const RefTooltipContent: FC = () => {
@@ -47,10 +45,7 @@ export const RefTooltipContent: FC = () => {
}
}}
>
<BootstrapVersionSwitcher
bs3={<Icon type="link" fw />}
bs5={<MaterialIcon type="link" />}
/>
<MaterialIcon type="link" />
{t('open_target')}
</OLButton>
</div>
@@ -6,11 +6,9 @@ import {
LiteralArgContent,
UrlArgument,
} from '../../lezer-latex/latex.terms.mjs'
import Icon from '../../../../shared/components/icon'
import { EditorState } from '@codemirror/state'
import { openURL } from '@/features/source-editor/utils/url'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
export const UrlTooltipContent: FC = () => {
@@ -30,10 +28,7 @@ export const UrlTooltipContent: FC = () => {
}
}}
>
<BootstrapVersionSwitcher
bs3={<Icon type="external-link" fw />}
bs5={<MaterialIcon type="open_in_new" />}
/>
<MaterialIcon type="open_in_new" />
{t('open_link')}
</OLButton>
</div>
@@ -2,15 +2,11 @@ import {
FigureModalSource,
useFigureModalContext,
} from './figure-modal-context'
import Icon from '../../../../shared/components/icon'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { sendMB } from '../../../../infrastructure/event-tracking'
import OLButton from '@/features/ui/components/ol/ol-button'
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
import MaterialIcon from '@/shared/components/material-icon'
import { bsVersion } from '@/features/utils/bootstrap-5'
import classnames from 'classnames'
export const FigureModalFooter: FC<{
onInsert: () => void
@@ -26,7 +22,6 @@ export const FigureModalFooter: FC<{
{t('cancel')}
</OLButton>
<FigureModalAction onInsert={onInsert} onDelete={onDelete} />
<BootstrapVersionSwitcher bs3={<div className="clearfix" />} />
</>
)
}
@@ -38,23 +33,12 @@ const HelpToggle = () => {
return (
<OLButton
variant="link"
className={classnames(
'figure-modal-help-link',
bsVersion({ bs3: 'pull-left', bs5: 'me-auto' })
)}
className="figure-modal-help-link me-auto"
onClick={() => dispatch({ helpShown: false })}
>
<BootstrapVersionSwitcher
bs3={<Icon type="arrow-left" fw />}
bs5={
<span>
<MaterialIcon
type="arrow_left_alt"
className="align-text-bottom"
/>
</span>
}
/>{' '}
<span>
<MaterialIcon type="arrow_left_alt" className="align-text-bottom" />
</span>{' '}
{t('back')}
</OLButton>
)
@@ -62,20 +46,12 @@ const HelpToggle = () => {
return (
<OLButton
variant="link"
className={classnames(
'figure-modal-help-link',
bsVersion({ bs3: 'pull-left', bs5: 'me-auto' })
)}
className="figure-modal-help-link me-auto"
onClick={() => dispatch({ helpShown: true })}
>
<BootstrapVersionSwitcher
bs3={<Icon type="question-circle" fw />}
bs5={
<span>
<MaterialIcon type="help" className="align-text-bottom" />
</span>
}
/>{' '}
<span>
<MaterialIcon type="help" className="align-text-bottom" />
</span>{' '}
{t('help')}
</OLButton>
)

Some files were not shown because too many files have changed in this diff Show More