mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
[web] Changes to recompile button in Bootstrap 5 (#21586)
* Add Story for `PdfCompileButton` * Set the CompileButton height so it's similar to BS3 * Add the CompileButton animations * Remove `sm` from CompileButton: makes font size bigger * Use MaterialIcon in compile-button dropdown-toggle * Use MaterialIcon in LayoutDropdown * Fix stripe alignment on Recompile button * Set padding around dropdown caret Per Alexandru's instructions * Prevent border from disappearing on hover * Set the padding of the compile button even on both sides Before: left 12px, right 16px; After: left 16px, right 16px; * Change px values to spacing var * Add some button classes for BS5 only * Don't render the hidden "Compiling…" in BS5, it changes the button width * Prevent `loading="[object Object]"` in the DOM Co-authored-by: Rebeka <rebeka.dekany@overleaf.com> --------- Co-authored-by: Rebeka <rebeka.dekany@overleaf.com> GitOrigin-RevId: 34f1eed03e63f3459243a37c878612a623f321f8
This commit is contained in:
parent
b0419a86f2
commit
1d4737ac69
8 changed files with 164 additions and 14 deletions
|
@ -10,6 +10,7 @@ import {
|
||||||
DropdownItem,
|
DropdownItem,
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownToggle,
|
DropdownToggle,
|
||||||
|
DropdownToggleCustom,
|
||||||
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
import Tooltip from '../../../shared/components/tooltip'
|
import Tooltip from '../../../shared/components/tooltip'
|
||||||
|
@ -136,7 +137,7 @@ const LayoutDropdownToggleButton = forwardRef<
|
||||||
onClick(e)
|
onClick(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <button {...props} ref={ref} onClick={handleClick} />
|
return <DropdownToggleCustom {...props} ref={ref} onClick={handleClick} />
|
||||||
})
|
})
|
||||||
LayoutDropdownToggleButton.displayName = 'LayoutDropdownToggleButton'
|
LayoutDropdownToggleButton.displayName = 'LayoutDropdownToggleButton'
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ function DetachCompileButton() {
|
||||||
size="sm"
|
size="sm"
|
||||||
isLoading={compiling}
|
isLoading={compiling}
|
||||||
bs3Props={{
|
bs3Props={{
|
||||||
loading: (
|
loading: compiling && (
|
||||||
<>
|
<>
|
||||||
<Icon type="refresh" spin={compiling} />
|
<Icon type="refresh" spin={compiling} />
|
||||||
<span className="detach-compile-button-label">
|
<span className="detach-compile-button-label">
|
||||||
|
@ -58,11 +58,14 @@ function DetachCompileButton() {
|
||||||
>
|
>
|
||||||
<BootstrapVersionSwitcher
|
<BootstrapVersionSwitcher
|
||||||
bs3={
|
bs3={
|
||||||
|
<>
|
||||||
|
<Icon type="refresh" spin={compiling} />
|
||||||
<span className="detach-compile-button-label">
|
<span className="detach-compile-button-label">
|
||||||
{compileButtonLabel}
|
{compileButtonLabel}
|
||||||
</span>
|
</span>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
bs5={compileButtonLabel}
|
bs5={t('recompile')}
|
||||||
/>
|
/>
|
||||||
</OLButton>
|
</OLButton>
|
||||||
</OLTooltip>
|
</OLTooltip>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import * as eventTracking from '../../../infrastructure/event-tracking'
|
||||||
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||||
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
||||||
import {
|
import {
|
||||||
|
DropdownToggleCustom,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
DropdownDivider,
|
DropdownDivider,
|
||||||
DropdownHeader,
|
DropdownHeader,
|
||||||
|
@ -18,7 +19,7 @@ import {
|
||||||
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
||||||
import OLButton from '@/features/ui/components/ol/ol-button'
|
import OLButton from '@/features/ui/components/ol/ol-button'
|
||||||
import OLButtonGroup from '@/features/ui/components/ol/ol-button-group'
|
import OLButtonGroup from '@/features/ui/components/ol/ol-button-group'
|
||||||
import { bsVersion } from '@/features/utils/bootstrap-5'
|
import { bsVersion, isBootstrap5 } from '@/features/utils/bootstrap-5'
|
||||||
import { useLayoutContext } from '@/shared/context/layout-context'
|
import { useLayoutContext } from '@/shared/context/layout-context'
|
||||||
|
|
||||||
const modifierKey = /Mac/i.test(navigator.platform) ? 'Cmd' : 'Ctrl'
|
const modifierKey = /Mac/i.test(navigator.platform) ? 'Cmd' : 'Ctrl'
|
||||||
|
@ -78,15 +79,18 @@ function PdfCompileButton() {
|
||||||
{
|
{
|
||||||
'detach-compile-button-animate': animateCompileDropdownArrow,
|
'detach-compile-button-animate': animateCompileDropdownArrow,
|
||||||
'btn-striped-animated': hasChanges,
|
'btn-striped-animated': hasChanges,
|
||||||
'no-left-border': true,
|
|
||||||
},
|
},
|
||||||
|
'no-left-border',
|
||||||
bsVersion({ bs5: 'dropdown-button-toggle' })
|
bsVersion({ bs5: 'dropdown-button-toggle' })
|
||||||
)
|
)
|
||||||
|
|
||||||
const buttonClassName = classNames({
|
const buttonClassName = classNames(
|
||||||
|
{
|
||||||
'btn-striped-animated': hasChanges,
|
'btn-striped-animated': hasChanges,
|
||||||
'no-left-radius': true,
|
'align-items-center py-0': isBootstrap5(),
|
||||||
})
|
},
|
||||||
|
'no-left-radius px-3'
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BootstrapVersionSwitcher
|
<BootstrapVersionSwitcher
|
||||||
|
@ -207,7 +211,11 @@ function PdfCompileButton() {
|
||||||
</SplitMenu>
|
</SplitMenu>
|
||||||
}
|
}
|
||||||
bs5={
|
bs5={
|
||||||
<Dropdown as={OLButtonGroup} autoClose="outside">
|
<Dropdown
|
||||||
|
as={OLButtonGroup}
|
||||||
|
autoClose="outside"
|
||||||
|
className="compile-button-group"
|
||||||
|
>
|
||||||
<OLTooltip
|
<OLTooltip
|
||||||
description={tooltipElement}
|
description={tooltipElement}
|
||||||
id="compile"
|
id="compile"
|
||||||
|
@ -219,7 +227,6 @@ function PdfCompileButton() {
|
||||||
>
|
>
|
||||||
<OLButton
|
<OLButton
|
||||||
variant="primary"
|
variant="primary"
|
||||||
size="sm"
|
|
||||||
disabled={compiling}
|
disabled={compiling}
|
||||||
isLoading={compiling}
|
isLoading={compiling}
|
||||||
onClick={() => startCompile()}
|
onClick={() => startCompile()}
|
||||||
|
@ -230,6 +237,7 @@ function PdfCompileButton() {
|
||||||
</OLTooltip>
|
</OLTooltip>
|
||||||
|
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
|
as={DropdownToggleCustom}
|
||||||
split
|
split
|
||||||
variant="primary"
|
variant="primary"
|
||||||
id="pdf-recompile-dropdown"
|
id="pdf-recompile-dropdown"
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
DropdownItem as BS5DropdownItem,
|
DropdownItem as BS5DropdownItem,
|
||||||
DropdownDivider as BS5DropdownDivider,
|
DropdownDivider as BS5DropdownDivider,
|
||||||
DropdownHeader as BS5DropdownHeader,
|
DropdownHeader as BS5DropdownHeader,
|
||||||
|
Button as BS5Button,
|
||||||
|
type ButtonProps,
|
||||||
} from 'react-bootstrap-5'
|
} from 'react-bootstrap-5'
|
||||||
import type {
|
import type {
|
||||||
DropdownProps,
|
DropdownProps,
|
||||||
|
@ -103,6 +105,20 @@ const ForwardReferredDropdownItem = fixedForwardRef(DropdownItem, {
|
||||||
|
|
||||||
export { ForwardReferredDropdownItem as DropdownItem }
|
export { ForwardReferredDropdownItem as DropdownItem }
|
||||||
|
|
||||||
|
export const DropdownToggleCustom = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
|
({ children, className, ...props }, ref) => (
|
||||||
|
<BS5Button
|
||||||
|
ref={ref}
|
||||||
|
className={classnames('custom-toggle', className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<MaterialIcon type="expand_more" />
|
||||||
|
</BS5Button>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
DropdownToggleCustom.displayName = 'CustomCaret'
|
||||||
|
|
||||||
export const DropdownToggle = forwardRef<
|
export const DropdownToggle = forwardRef<
|
||||||
typeof BS5DropdownToggle,
|
typeof BS5DropdownToggle,
|
||||||
DropdownToggleProps
|
DropdownToggleProps
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { FC } from 'react'
|
||||||
|
import type { Meta } from '@storybook/react'
|
||||||
|
import PdfCompileButton from '@/features/pdf-preview/components/pdf-compile-button'
|
||||||
|
import { ScopeDecorator } from '../decorators/scope'
|
||||||
|
import { CompileContext } from '@/shared/context/local-compile-context'
|
||||||
|
import { DetachCompileContext } from '@/shared/context/detach-compile-context'
|
||||||
|
import { bsVersionDecorator } from '../../../.storybook/utils/with-bootstrap-switcher'
|
||||||
|
|
||||||
|
export const CompileButton: FC<CompileContext> = (props: CompileContext) => (
|
||||||
|
<DetachCompileContext.Provider value={props}>
|
||||||
|
<div className="pdf m-5">
|
||||||
|
<div className="toolbar toolbar-pdf toolbar-pdf-hybrid btn-toolbar">
|
||||||
|
<div className="toolbar-pdf-left">
|
||||||
|
<PdfCompileButton />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DetachCompileContext.Provider>
|
||||||
|
)
|
||||||
|
|
||||||
|
const args: Partial<CompileContext> = {
|
||||||
|
autoCompile: false,
|
||||||
|
compiling: false,
|
||||||
|
draft: false,
|
||||||
|
hasChanges: false,
|
||||||
|
stopOnFirstError: false,
|
||||||
|
stopOnValidationError: false,
|
||||||
|
animateCompileDropdownArrow: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
const meta: Meta<typeof CompileButton> = {
|
||||||
|
title: 'Editor / Toolbar / Compile Button',
|
||||||
|
component: CompileButton,
|
||||||
|
// @ts-ignore
|
||||||
|
decorators: [ScopeDecorator],
|
||||||
|
argTypes: {
|
||||||
|
...bsVersionDecorator.argTypes,
|
||||||
|
startCompile: { action: 'startCompile' },
|
||||||
|
setAutoCompile: { action: 'setAutoCompile' },
|
||||||
|
setCompiling: { action: 'setCompiling' },
|
||||||
|
setDraft: { action: 'setDraft' },
|
||||||
|
setStopOnFirstError: { action: 'setStopOnFirstError' },
|
||||||
|
setError: { action: 'setError' },
|
||||||
|
setHasLintingError: { action: 'setHasLintingError' },
|
||||||
|
setPosition: { action: 'setPosition' },
|
||||||
|
setStopOnValidationError: { action: 'setStopOnValidationError' },
|
||||||
|
recompileFromScratch: { action: 'recompileFromScratch' },
|
||||||
|
stopCompile: { action: 'stopCompile' },
|
||||||
|
setAnimateCompileDropdownArrow: {
|
||||||
|
action: 'setAnimateCompileDropdownArrow',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default meta
|
|
@ -1,5 +1,20 @@
|
||||||
.dropdown {
|
.dropdown {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
||||||
|
.no-left-border {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-toggle {
|
||||||
|
&::after {
|
||||||
|
content: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
padding-left: var(--spacing-04);
|
||||||
|
padding-right: var(--spacing-05);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-header {
|
.dropdown-header {
|
||||||
|
|
|
@ -29,3 +29,43 @@ $stripe-width: 20px;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes compile-button-flash {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
background: rgb(0 0 0 / 0%);
|
||||||
|
}
|
||||||
|
|
||||||
|
25%,
|
||||||
|
75% {
|
||||||
|
background: rgb(0 0 0 / 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes compile-button-bounce {
|
||||||
|
0%,
|
||||||
|
50%,
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
25%,
|
||||||
|
75% {
|
||||||
|
transform: translateY(2px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detach-compile-button-animate {
|
||||||
|
animation-duration: 1.2s;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation-timing-function: ease-in-out;
|
||||||
|
animation-name: compile-button-flash;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detach-compile-button-animate .material-symbols {
|
||||||
|
animation-duration: 0.6s;
|
||||||
|
animation-delay: 0.4s;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
||||||
|
animation-name: compile-button-bounce;
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,17 @@
|
||||||
.toolbar-pdf-left {
|
.toolbar-pdf-left {
|
||||||
gap: var(--spacing-02);
|
gap: var(--spacing-02);
|
||||||
|
|
||||||
|
.compile-button-group {
|
||||||
|
height: 28px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
background-color: var(--bg-accent-01);
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
z-index: auto; // prevents border from being hidden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown > .btn {
|
.dropdown > .btn {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
|
|
Loading…
Reference in a new issue