mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Merge pull request #35037 from overleaf/mj-themed-modals-again
[web] Add support for dark mode modals GitOrigin-RevId: 34770a6f91d6a331cfaccf86c7dc1a5d151ad25b
This commit is contained in:
committed by
Copybot
parent
ef8fce67f1
commit
3c3dd0fb37
@@ -497,6 +497,7 @@ const _ProjectController = {
|
||||
'ai-disabled-collaborators',
|
||||
'group-link-sharing',
|
||||
'compile-with-checkpoint',
|
||||
'themed-modals',
|
||||
].filter(Boolean)
|
||||
|
||||
const getUserValues = async userId =>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from '../context/settings-modal-context'
|
||||
import useFocusOnSetting from '../hooks/use-focus-on-setting'
|
||||
import useOpenSettingsViaQueryParam from '../hooks/use-open-settings-via-query-param'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
|
||||
const SettingsModalWrapper = () => {
|
||||
return (
|
||||
@@ -25,6 +26,7 @@ const SettingsModal = () => {
|
||||
const { t } = useTranslation()
|
||||
const { show, setShow, settingsTabs, activeTab, setActiveTab } =
|
||||
useSettingsModalContext()
|
||||
const themed = useFeatureFlag('themed-modals')
|
||||
|
||||
useFocusOnSetting()
|
||||
useOpenSettingsViaQueryParam()
|
||||
@@ -39,6 +41,7 @@ const SettingsModal = () => {
|
||||
? 'ide-settings-modal-transparent-backdrop'
|
||||
: undefined
|
||||
}
|
||||
themed={themed}
|
||||
>
|
||||
<OLModalHeader>
|
||||
<OLModalTitle>{t('settings')}</OLModalTitle>
|
||||
|
||||
@@ -9,11 +9,14 @@ import {
|
||||
import { ModalBodyProps } from 'react-bootstrap/ModalBody'
|
||||
import type { Options as FocusTrapOptions } from 'focus-trap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import classNames from 'classnames'
|
||||
|
||||
type OLModalProps = ModalProps & {
|
||||
size?: 'sm' | 'lg'
|
||||
onHide: () => void
|
||||
show?: boolean
|
||||
themed?: boolean
|
||||
className?: string
|
||||
} & Pick<
|
||||
FocusTrapOptions,
|
||||
| 'escapeDeactivates'
|
||||
@@ -34,10 +37,22 @@ export function OLModal({
|
||||
escapeDeactivates = false, // Let React-Bootstrap Modal handle Escape key to avoid double Escape key handling
|
||||
clickOutsideDeactivates = true, // Allow focus trap to deactivate on outside click and let React-Bootstrap Modal handle it
|
||||
initialFocus,
|
||||
themed = false,
|
||||
className,
|
||||
backdropClassName,
|
||||
...props
|
||||
}: OLModalProps) {
|
||||
return (
|
||||
<Modal show={show} onHide={onHide} {...props}>
|
||||
<Modal
|
||||
show={show}
|
||||
onHide={onHide}
|
||||
className={classNames({ 'modal-themed': themed }, className)}
|
||||
backdropClassName={classNames(
|
||||
{ 'modal-backdrop-themed': themed },
|
||||
backdropClassName
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<FocusTrap
|
||||
active={show}
|
||||
focusTrapOptions={{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
}
|
||||
|
||||
@include theme('default') {
|
||||
.modal {
|
||||
.modal:not(.modal-themed) {
|
||||
// Until we add a dark modal version, all core components in modals should use light theme
|
||||
@include light-dropdown-menu;
|
||||
@include light-notification;
|
||||
@@ -18,6 +18,27 @@
|
||||
@include light-buttons;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-themed {
|
||||
--bs-modal-color: var(--content-primary-dark);
|
||||
--bs-modal-bg: var(--bg-dark-primary);
|
||||
--bs-modal-border-color: var(--border-divider-dark);
|
||||
--bs-modal-box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 40%);
|
||||
--bs-modal-header-border-color: var(--border-divider-dark);
|
||||
--bs-modal-footer-bg: var(--bg-dark-secondary);
|
||||
--bs-modal-footer-border-color: var(--border-divider-dark);
|
||||
--bs-heading-color: var(--content-primary-dark);
|
||||
|
||||
color-scheme: dark;
|
||||
|
||||
.modal-header .btn-close {
|
||||
--bs-btn-close-bg: url('data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23fff%27%3e%3cpath d=%27M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414%27/%3e%3c/svg%3e');
|
||||
}
|
||||
}
|
||||
|
||||
.modal-backdrop-themed {
|
||||
background-color: var(--neutral-70);
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
:root {
|
||||
--ide-settings-text-color: var(--content-primary);
|
||||
--ide-settings-section-title-color: var(--content-secondary);
|
||||
--ide-settings-description-color: var(--content-secondary);
|
||||
--ide-settings-section-title-border-color: var(--border-divider);
|
||||
--ide-settings-link-hover-color: var(--link-ui-hover);
|
||||
--ide-settings-link-hover-bg-color: var(--bg-light-secondary);
|
||||
--ide-settings-link-active-color: var(--green-70);
|
||||
--ide-settings-link-active-bg-color: var(--bg-accent-03);
|
||||
}
|
||||
|
||||
@include theme('default') {
|
||||
.modal-themed {
|
||||
--ide-settings-text-color: var(--content-primary-dark);
|
||||
--ide-settings-section-title-color: var(--content-secondary-dark);
|
||||
--ide-settings-description-color: var(--content-secondary-dark);
|
||||
--ide-settings-section-title-border-color: var(--border-divider-dark);
|
||||
--ide-settings-link-hover-color: var(--link-ui-hover-dark);
|
||||
--ide-settings-link-hover-bg-color: var(--bg-dark-secondary);
|
||||
--ide-settings-link-active-color: var(--green-10);
|
||||
--ide-settings-link-active-bg-color: var(--green-70);
|
||||
}
|
||||
}
|
||||
|
||||
.ide-settings-tab-nav.nav {
|
||||
width: 300px;
|
||||
border-right: var(--bs-modal-header-border-width) solid
|
||||
@@ -25,7 +49,7 @@
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
gap: var(--spacing-02);
|
||||
color: var(--content-primary);
|
||||
color: var(--ide-settings-text-color);
|
||||
padding: var(--spacing-02);
|
||||
border-radius: var(--border-radius-base);
|
||||
font-size: var(--font-size-02);
|
||||
@@ -33,24 +57,24 @@
|
||||
text-decoration: none;
|
||||
|
||||
&:visited {
|
||||
color: var(--content-primary);
|
||||
color: var(--ide-settings-text-color);
|
||||
}
|
||||
|
||||
&.ide-settings-tab-link-button:hover:not(.active),
|
||||
&.ide-settings-tab-link-button:focus:not(.active) {
|
||||
background-color: var(--bg-light-secondary);
|
||||
color: var(--content-primary);
|
||||
background-color: var(--ide-settings-link-hover-bg-color);
|
||||
color: var(--ide-settings-text-color);
|
||||
}
|
||||
|
||||
&.ide-settings-tab-link-anchor:hover,
|
||||
&.ide-settings-tab-link-anchor:focus {
|
||||
color: var(--link-ui-hover);
|
||||
background-color: var(--bg-light-secondary);
|
||||
color: var(--ide-settings-link-hover-color);
|
||||
background-color: var(--ide-settings-link-hover-bg-color);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--green-70);
|
||||
background-color: var(--bg-accent-03);
|
||||
color: var(--ide-settings-link-active-color);
|
||||
background-color: var(--ide-settings-link-active-bg-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@@ -72,11 +96,11 @@
|
||||
}
|
||||
|
||||
.ide-settings-section-title {
|
||||
color: var(--content-secondary);
|
||||
color: var(--ide-settings-section-title-color);
|
||||
font-size: var(--font-size-01);
|
||||
line-height: var(--line-height-01);
|
||||
padding-bottom: var(--spacing-06);
|
||||
border-bottom: 1px solid var(--border-divider);
|
||||
border-bottom: 1px solid var(--ide-settings-section-title-border-color);
|
||||
margin: 0 var(--spacing-04);
|
||||
}
|
||||
|
||||
@@ -99,12 +123,12 @@
|
||||
}
|
||||
|
||||
.ide-setting-title {
|
||||
color: var(--content-primary);
|
||||
color: var(--ide-settings-text-color);
|
||||
font-size: var(--font-size-02);
|
||||
}
|
||||
|
||||
.ide-setting-description {
|
||||
color: var(--content-secondary);
|
||||
color: var(--ide-settings-description-color);
|
||||
font-size: var(--font-size-02);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user