mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #21815 from overleaf/td-bs5-references-search
[BS5] Migrate references search modal GitOrigin-RevId: 65496840e32af09e5ae7351aa1789ebf5cac5083
This commit is contained in:
parent
73b17dd694
commit
daaff1d9c6
9 changed files with 127 additions and 19 deletions
|
@ -1,13 +1,16 @@
|
||||||
import { forwardRef } from 'react'
|
import { forwardRef } from 'react'
|
||||||
import { Form, FormControlProps } from 'react-bootstrap-5'
|
import {
|
||||||
|
Form,
|
||||||
|
FormControlProps as BS5FormControlProps,
|
||||||
|
} from 'react-bootstrap-5'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
|
||||||
type OLFormControlProps = FormControlProps & {
|
type FormControlProps = BS5FormControlProps & {
|
||||||
prepend?: React.ReactNode
|
prepend?: React.ReactNode
|
||||||
append?: React.ReactNode
|
append?: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormControl = forwardRef<HTMLInputElement, OLFormControlProps>(
|
const FormControl = forwardRef<HTMLInputElement, FormControlProps>(
|
||||||
({ prepend, append, className, ...props }, ref) => {
|
({ prepend, append, className, ...props }, ref) => {
|
||||||
if (prepend || append) {
|
if (prepend || append) {
|
||||||
const wrapperClassNames = classnames('form-control-wrapper', {
|
const wrapperClassNames = classnames('form-control-wrapper', {
|
||||||
|
|
|
@ -3,11 +3,14 @@ import { getAriaAndDataProps } from '@/features/utils/bootstrap-5'
|
||||||
import FormControl from '@/features/ui/components/bootstrap-5/form/form-control'
|
import FormControl from '@/features/ui/components/bootstrap-5/form/form-control'
|
||||||
import BS3FormControl from '@/features/ui/components/bootstrap-3/form/form-control'
|
import BS3FormControl from '@/features/ui/components/bootstrap-3/form/form-control'
|
||||||
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||||
|
import OLSpinner from '@/features/ui/components/ol/ol-spinner'
|
||||||
|
import Icon from '@/shared/components/icon'
|
||||||
|
|
||||||
type OLFormControlProps = ComponentProps<typeof FormControl> & {
|
type OLFormControlProps = ComponentProps<typeof FormControl> & {
|
||||||
bs3Props?: Record<string, unknown>
|
bs3Props?: Record<string, unknown>
|
||||||
'data-ol-dirty'?: unknown
|
'data-ol-dirty'?: unknown
|
||||||
'main-field'?: any // For the CM6's benefit in the editor search panel
|
'main-field'?: any // For the CM6's benefit in the editor search panel
|
||||||
|
loading?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type BS3FormControlProps = ComponentProps<typeof BS3FormControl> & {
|
type BS3FormControlProps = ComponentProps<typeof BS3FormControl> & {
|
||||||
|
@ -16,7 +19,7 @@ type BS3FormControlProps = ComponentProps<typeof BS3FormControl> & {
|
||||||
|
|
||||||
const OLFormControl = forwardRef<HTMLInputElement, OLFormControlProps>(
|
const OLFormControl = forwardRef<HTMLInputElement, OLFormControlProps>(
|
||||||
(props, ref) => {
|
(props, ref) => {
|
||||||
const { bs3Props, ...rest } = props
|
const { bs3Props, append, ...rest } = props
|
||||||
|
|
||||||
// Use a callback so that the ref passed to the BS3 FormControl is stable
|
// Use a callback so that the ref passed to the BS3 FormControl is stable
|
||||||
const bs3InputRef = useCallback(
|
const bs3InputRef = useCallback(
|
||||||
|
@ -55,7 +58,6 @@ const OLFormControl = forwardRef<HTMLInputElement, OLFormControlProps>(
|
||||||
onBlur: rest.onBlur as BS3FormControlProps['onBlur'],
|
onBlur: rest.onBlur as BS3FormControlProps['onBlur'],
|
||||||
onInvalid: rest.onInvalid as BS3FormControlProps['onInvalid'],
|
onInvalid: rest.onInvalid as BS3FormControlProps['onInvalid'],
|
||||||
prepend: rest.prepend,
|
prepend: rest.prepend,
|
||||||
append: rest.append,
|
|
||||||
size: rest.htmlSize,
|
size: rest.htmlSize,
|
||||||
'main-field': rest['main-field'],
|
'main-field': rest['main-field'],
|
||||||
...bs3Props,
|
...bs3Props,
|
||||||
|
@ -69,8 +71,19 @@ const OLFormControl = forwardRef<HTMLInputElement, OLFormControlProps>(
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BootstrapVersionSwitcher
|
<BootstrapVersionSwitcher
|
||||||
bs3={<BS3FormControl {...bs3FormControlProps} />}
|
bs3={
|
||||||
bs5={<FormControl ref={ref} {...rest} />}
|
<BS3FormControl
|
||||||
|
{...bs3FormControlProps}
|
||||||
|
append={rest.loading ? <Icon type="spinner" spin /> : append}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
bs5={
|
||||||
|
<FormControl
|
||||||
|
ref={ref}
|
||||||
|
{...rest}
|
||||||
|
append={rest.loading ? <OLSpinner size="sm" /> : append}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,27 +2,38 @@ import { FormGroupProps } from 'react-bootstrap-5'
|
||||||
import {
|
import {
|
||||||
FormGroup as BS3FormGroup,
|
FormGroup as BS3FormGroup,
|
||||||
FormGroupProps as BS3FormGroupProps,
|
FormGroupProps as BS3FormGroupProps,
|
||||||
|
FormControl,
|
||||||
} from 'react-bootstrap'
|
} from 'react-bootstrap'
|
||||||
import FormGroup from '@/features/ui/components/bootstrap-5/form/form-group'
|
import FormGroup from '@/features/ui/components/bootstrap-5/form/form-group'
|
||||||
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
type OLFormGroupProps = FormGroupProps & {
|
type OLFormGroupProps = FormGroupProps & {
|
||||||
bs3Props?: Record<string, unknown>
|
bs3Props?: {
|
||||||
|
withFeedback?: boolean
|
||||||
|
hiddenLabel?: boolean
|
||||||
|
validationState?: BS3FormGroupProps['validationState']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function OLFormGroup(props: OLFormGroupProps) {
|
function OLFormGroup(props: OLFormGroupProps) {
|
||||||
const { bs3Props, className, ...rest } = props
|
const { bs3Props, className, ...rest } = props
|
||||||
|
const { withFeedback, hiddenLabel, ...bs3PropsRest } = bs3Props || {}
|
||||||
|
|
||||||
const bs3FormGroupProps: BS3FormGroupProps = {
|
const bs3FormGroupProps: BS3FormGroupProps = {
|
||||||
children: rest.children,
|
|
||||||
controlId: rest.controlId,
|
controlId: rest.controlId,
|
||||||
className,
|
className: classNames(className, { 'hidden-label': hiddenLabel }),
|
||||||
...bs3Props,
|
...bs3PropsRest,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BootstrapVersionSwitcher
|
<BootstrapVersionSwitcher
|
||||||
bs3={<BS3FormGroup {...bs3FormGroupProps} />}
|
bs3={
|
||||||
|
<BS3FormGroup {...bs3FormGroupProps}>
|
||||||
|
{rest.children}
|
||||||
|
{withFeedback ? <FormControl.Feedback /> : null}
|
||||||
|
</BS3FormGroup>
|
||||||
|
}
|
||||||
bs5={<FormGroup className={className} {...rest} />}
|
bs5={<FormGroup className={className} {...rest} />}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import classnames from 'classnames'
|
||||||
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
||||||
import MaterialIcon from '@/shared/components/material-icon'
|
import MaterialIcon from '@/shared/components/material-icon'
|
||||||
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||||
|
import { bsVersion } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
type TooltipProps = {
|
type TooltipProps = {
|
||||||
id: string
|
id: string
|
||||||
|
@ -30,7 +31,9 @@ const BetaBadge: FC<{
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||||
<span className="sr-only">{tooltip.text}</span>
|
<span className={bsVersion({ bs5: 'visually-hidden', bs3: 'sr-only' })}>
|
||||||
|
{tooltip.text}
|
||||||
|
</span>
|
||||||
<BootstrapVersionSwitcher
|
<BootstrapVersionSwitcher
|
||||||
bs3={<span className={classnames('badge', badgeClass)} />}
|
bs3={<span className={classnames('badge', badgeClass)} />}
|
||||||
bs5={
|
bs5={
|
||||||
|
|
|
@ -519,8 +519,7 @@ CodeMirror
|
||||||
padding-left: 38px;
|
padding-left: 38px;
|
||||||
padding-right: 38px;
|
padding-right: 38px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
background: white;
|
background: rgba(255, 255, 255, 0.95);
|
||||||
opacity: 0.95;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
.message {
|
.message {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
|
@ -531,9 +530,6 @@ CodeMirror
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.btn {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.search-form {
|
.search-form {
|
||||||
|
|
|
@ -147,7 +147,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control-start-icon {
|
.form-control-start-icon {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
@import 'editor/review-panel-new';
|
@import 'editor/review-panel-new';
|
||||||
@import 'editor/table-generator-column-width-modal';
|
@import 'editor/table-generator-column-width-modal';
|
||||||
@import 'editor/math-preview';
|
@import 'editor/math-preview';
|
||||||
|
@import 'editor/references-search';
|
||||||
@import 'website-redesign';
|
@import 'website-redesign';
|
||||||
@import 'group-settings';
|
@import 'group-settings';
|
||||||
@import 'templates-v2';
|
@import 'templates-v2';
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
.references-search-modal {
|
||||||
|
.references-search-upgrade-prompt {
|
||||||
|
padding: var(--spacing-08);
|
||||||
|
padding-bottom: var(--spacing-11);
|
||||||
|
|
||||||
|
.upgrade-prompt {
|
||||||
|
text-align: center;
|
||||||
|
width: 400px;
|
||||||
|
padding: var(--spacing-06) var(--spacing-10);
|
||||||
|
margin: auto;
|
||||||
|
background: rgb($white, 0.95);
|
||||||
|
border-radius: var(--border-radius-medium);
|
||||||
|
|
||||||
|
.message {
|
||||||
|
margin-top: var(--spacing-06);
|
||||||
|
|
||||||
|
&.call-to-action {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.upgrade-benefits {
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
margin-top: var(--spacing-05);
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// search result items list
|
||||||
|
.search-results {
|
||||||
|
font-size: var(--font-size-01);
|
||||||
|
|
||||||
|
.no-results-message,
|
||||||
|
.too-many-results-message {
|
||||||
|
font-size: var(--font-size-03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-results-scroll-container {
|
||||||
|
max-height: calc(100vh - 225px);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-hit {
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
border-bottom: 1px solid var(--border-divider);
|
||||||
|
padding: var(--spacing-04);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
border-left: var(--spacing-02) solid transparent;
|
||||||
|
|
||||||
|
&.selected-search-result-hit {
|
||||||
|
color: var(--content-positive);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hit-title {
|
||||||
|
font-size: var(--font-size-03);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -159,6 +159,7 @@ output {
|
||||||
height: auto;
|
height: auto;
|
||||||
border-radius: @border-radius-base;
|
border-radius: @border-radius-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smaller border-radius for `select` inputs
|
// Smaller border-radius for `select` inputs
|
||||||
select& {
|
select& {
|
||||||
border-radius: @border-radius-base;
|
border-radius: @border-radius-base;
|
||||||
|
@ -295,6 +296,11 @@ input[type='checkbox'],
|
||||||
line-height: @input-height-base;
|
line-height: @input-height-base;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Position the feedback inside the input element when there's no label
|
||||||
|
&.hidden-label .form-control-feedback {
|
||||||
|
margin-top: -(@line-height-computed + 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-feedback-left {
|
.has-feedback-left {
|
||||||
|
|
Loading…
Reference in a new issue