+
- {!this.searchInput &&
- this.sortOptions.length > 1 &&
- this.renderSortBar()}
+ {this.renderSearchBar()}
-
- {this.searchInput
- ? this.renderSearchResults()
- : this.isMultiMode
- ? this.renderAllEntitiesInMultiMode()
- : this.renderAllEntitiesInSingleMode()}
+
+ {!this.searchInput &&
+ this.sortOptions.length > 1 &&
+ this.renderSortBar()}
+
+
+ {this.searchInput
+ ? this.renderSearchResults()
+ : this.isMultiMode
+ ? this.renderAllEntitiesInMultiMode()
+ : this.renderAllEntitiesInSingleMode()}
+
{this.renderFooter()}
diff --git a/packages/@ourworldindata/grapher/src/modal/DownloadModal.scss b/packages/@ourworldindata/grapher/src/modal/DownloadModal.scss
index cafd18859c5..07e180b9137 100644
--- a/packages/@ourworldindata/grapher/src/modal/DownloadModal.scss
+++ b/packages/@ourworldindata/grapher/src/modal/DownloadModal.scss
@@ -1,8 +1,23 @@
.download-modal-content {
color: $dark-text;
- padding: 0 var(--modal-padding) var(--modal-padding);
- min-height: 45px;
- position: relative;
+
+ // necessary for scrolling
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ > * {
+ flex-shrink: 0;
+ }
+
+ .scrollable {
+ flex: 1 1 auto;
+ overflow-y: auto;
+ padding: 0 var(--modal-padding) var(--modal-padding);
+
+ // needed for the loading indicator
+ position: relative;
+ min-height: 45px;
+ }
.grouped-menu-section {
h3 {
diff --git a/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx b/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx
index 2f8d0f5fa94..1529a82091d 100644
--- a/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx
+++ b/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx
@@ -20,6 +20,7 @@ import {
} from "@ourworldindata/core-table"
import { Modal } from "./Modal"
import { GrapherExport } from "../captionedChart/StaticChartRasterizer.js"
+import { OverlayHeader } from "../core/OverlayHeader.js"
export interface DownloadModalManager {
displaySlug: string
@@ -362,17 +363,22 @@ export class DownloadModal extends React.Component
{
render(): JSX.Element {
return (
-
-
- {this.isReady ? (
- this.renderReady()
- ) : (
-
- )}
+
+
+
+
+ {this.isReady ? (
+ this.renderReady()
+ ) : (
+
+ )}
+
)
diff --git a/packages/@ourworldindata/grapher/src/modal/EmbedModal.scss b/packages/@ourworldindata/grapher/src/modal/EmbedModal.scss
index f88795663ac..954228136fc 100644
--- a/packages/@ourworldindata/grapher/src/modal/EmbedModal.scss
+++ b/packages/@ourworldindata/grapher/src/modal/EmbedModal.scss
@@ -1,6 +1,19 @@
.embed-modal-content {
color: $dark-text;
- margin: 0 var(--modal-padding) var(--modal-padding);
+
+ // necessary for scrolling
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ > * {
+ flex-shrink: 0;
+ }
+
+ .scrollable {
+ flex: 1 1 auto;
+ overflow-y: auto;
+ padding: 0 var(--modal-padding) var(--modal-padding);
+ }
p {
margin-bottom: 16px;
diff --git a/packages/@ourworldindata/grapher/src/modal/EmbedModal.tsx b/packages/@ourworldindata/grapher/src/modal/EmbedModal.tsx
index ab6bc066943..0baa0cf011a 100644
--- a/packages/@ourworldindata/grapher/src/modal/EmbedModal.tsx
+++ b/packages/@ourworldindata/grapher/src/modal/EmbedModal.tsx
@@ -4,6 +4,7 @@ import { computed, action } from "mobx"
import { Bounds, DEFAULT_BOUNDS } from "@ourworldindata/utils"
import { Modal } from "./Modal"
import { CodeSnippet } from "@ourworldindata/components"
+import { OverlayHeader } from "../core/OverlayHeader.js"
export interface EmbedModalManager {
canonicalUrl?: string
@@ -45,17 +46,22 @@ export class EmbedModal extends React.Component
{
render(): JSX.Element {
return (
-
-
- Paste this into any HTML page:
-
-
- {this.manager.embedDialogAdditionalElements}
+
+
+
+
+ Paste this into any HTML page:
+
+
+ {this.manager.embedDialogAdditionalElements}
+
)
diff --git a/packages/@ourworldindata/grapher/src/modal/EntitySelectorModal.tsx b/packages/@ourworldindata/grapher/src/modal/EntitySelectorModal.tsx
index a6604f4140e..8ecbb0867da 100644
--- a/packages/@ourworldindata/grapher/src/modal/EntitySelectorModal.tsx
+++ b/packages/@ourworldindata/grapher/src/modal/EntitySelectorModal.tsx
@@ -11,7 +11,6 @@ import {
export interface EntitySelectorModalManager extends EntitySelectorManager {
isEntitySelectorModalOrDrawerOpen?: boolean
frameBounds?: Bounds
- entitySelectorTitle?: string
}
@observer
@@ -39,7 +38,6 @@ export class EntitySelectorModal extends React.Component<{
render(): JSX.Element {
return (
void
- title?: string
children?: React.ReactNode
isHeightFixed?: boolean // by default, the modal height is not fixed but fits to the content
alignVertical?: "center" | "bottom"
- showStickyHeader?: boolean
}> {
contentRef: React.RefObject = React.createRef()
@@ -22,10 +17,6 @@ export class Modal extends React.Component<{
return this.props.bounds
}
- @computed private get title(): string | undefined {
- return this.props.title
- }
-
@computed private get isHeightFixed(): boolean {
return this.props.isHeightFixed ?? false
}
@@ -34,10 +25,6 @@ export class Modal extends React.Component<{
return this.props.alignVertical ?? "center"
}
- @computed private get showStickyHeader(): boolean {
- return this.props.showStickyHeader || !!this.title
- }
-
@action.bound onDocumentClick(e: MouseEvent): void {
const tagName = (e.target as HTMLElement).tagName
const isTargetInteractive = ["A", "BUTTON", "INPUT"].includes(tagName)
@@ -95,27 +82,7 @@ export class Modal extends React.Component<{
style={contentStyle}
ref={this.contentRef}
>
- {this.showStickyHeader ? (
-
-
- {this.title}
-
-
-
- ) : (
-
- )}
-
- {this.props.children}
-
+ {this.props.children}
diff --git a/packages/@ourworldindata/grapher/src/modal/SourcesModal.scss b/packages/@ourworldindata/grapher/src/modal/SourcesModal.scss
index 9a636d7a837..a9f015a9c56 100644
--- a/packages/@ourworldindata/grapher/src/modal/SourcesModal.scss
+++ b/packages/@ourworldindata/grapher/src/modal/SourcesModal.scss
@@ -7,12 +7,36 @@
$border: #e7e7e7;
- max-width: $max-content-width;
- margin: 0 auto;
- padding: 0 var(--modal-padding) var(--modal-padding);
+ // necessary for scrolling
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ > * {
+ flex-shrink: 0;
+ }
+
+ .scrollable {
+ max-width: $max-content-width;
+ margin: 0 auto;
+
+ flex: 1 1 auto;
+ overflow-y: auto;
+ padding: 0 var(--modal-padding) var(--modal-padding);
+
+ &--pad-top {
+ padding-top: var(--modal-padding);
+ }
+
+ // needed for the loading indicator
+ position: relative;
+ min-height: 45px;
+ }
- &.sources-modal-content--pad-top {
- margin-top: var(--modal-padding);
+ .close-button--top-right {
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin: var(--modal-padding);
}
.note-multiple-indicators {
diff --git a/packages/@ourworldindata/grapher/src/modal/SourcesModal.tsx b/packages/@ourworldindata/grapher/src/modal/SourcesModal.tsx
index bc3b6ed66f0..d4c034cff3b 100644
--- a/packages/@ourworldindata/grapher/src/modal/SourcesModal.tsx
+++ b/packages/@ourworldindata/grapher/src/modal/SourcesModal.tsx
@@ -36,8 +36,9 @@ import { SourcesDescriptions } from "./SourcesDescriptions"
import { Tabs } from "../tabs/Tabs"
import { ExpandableTabs } from "../tabs/ExpandableTabs"
import { LoadingIndicator } from "../loadingIndicator/LoadingIndicator"
-import { CLOSE_BUTTON_WIDTH } from "../closeButton/CloseButton"
+import { CLOSE_BUTTON_WIDTH, CloseButton } from "../closeButton/CloseButton"
import { isContinentsVariableId } from "../core/GrapherConstants"
+import { OverlayHeader } from "../core/OverlayHeader.js"
// keep in sync with variables in SourcesModal.scss
const MAX_CONTENT_WIDTH = 640
@@ -92,7 +93,7 @@ export class SourcesModal extends React.Component<
return this.frameBounds.padHeight(15).padWidth(padWidth)
}
- @computed private get showStickyModalHeader(): boolean {
+ @computed private get showStickyHeader(): boolean {
const modalWidth = this.modalBounds.width - 2 * this.modalPadding
return (modalWidth - MAX_CONTENT_WIDTH) / 2 < CLOSE_BUTTON_WIDTH + 2
}
@@ -262,19 +263,27 @@ export class SourcesModal extends React.Component<
bounds={this.modalBounds}
isHeightFixed={true}
onDismiss={this.onDismiss}
- showStickyHeader={this.showStickyModalHeader}
>
-
- {this.manager.isReady ? (
- this.renderModalContent()
+
+ {this.showStickyHeader ? (
+
) : (
-
+
)}
+
+ {this.manager.isReady ? (
+ this.renderModalContent()
+ ) : (
+
+ )}
+
)
diff --git a/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.scss b/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.scss
index a0b4a725640..14cc01d4ea6 100644
--- a/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.scss
+++ b/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.scss
@@ -3,19 +3,8 @@
flex-shrink: 0;
border-left: 1px solid $frame-color;
- position: relative;
-
- // necessary for scrolling
- display: flex;
- flex-direction: column;
-
- .side-panel__header {
- margin: 16px;
- flex-shrink: 0; // necessary for scrolling
- }
-
- .side-panel__scrollable {
- flex-grow: 1;
- overflow-y: auto;
+ // don't show close button in the side panel header
+ .overlay-header .close-button {
+ display: none;
}
}
diff --git a/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.tsx b/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.tsx
index d12567f2d01..59d748692b8 100644
--- a/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.tsx
+++ b/packages/@ourworldindata/grapher/src/sidePanel/SidePanel.tsx
@@ -1,14 +1,12 @@
import React from "react"
-import cx from "classnames"
import { observer } from "mobx-react"
import { computed } from "mobx"
import { Bounds } from "@ourworldindata/utils"
-import { GRAPHER_SCROLLABLE_CONTAINER_CLASS } from "../core/GrapherConstants"
+import { GRAPHER_SIDE_PANEL_CLASS } from "../core/GrapherConstants.js"
@observer
export class SidePanel extends React.Component<{
bounds: Bounds
- title: string
children: React.ReactNode
}> {
@computed private get bounds(): Bounds {
@@ -18,23 +16,13 @@ export class SidePanel extends React.Component<{
render(): JSX.Element {
return (
-
- {this.props.title}
-
-
- {this.props.children}
-
+ {this.props.children}
)
}
diff --git a/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.scss b/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.scss
index 1649aa6a87b..84b40363286 100644
--- a/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.scss
+++ b/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.scss
@@ -16,35 +16,7 @@
width: 300px;
height: 100vh;
z-index: $zindex-controls-drawer;
- overflow-y: scroll;
background: white;
-
- // necessary for scrolling
- display: flex;
- flex-direction: column;
-
- .grapher-drawer-header {
- position: static;
- display: flex;
- justify-content: space-between;
- align-items: center;
- background: white;
- padding: 16px;
- position: sticky;
- top: 0;
- z-index: 1;
-
- flex-shrink: 0; // necessary for scrolling
-
- button {
- margin-left: 8px;
- }
- }
-
- .grapher-drawer-scrollable {
- overflow-y: auto;
- flex-grow: 1;
- }
}
.grapher-drawer-backdrop {
diff --git a/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.tsx b/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.tsx
index a763f36a0b3..2a17cdee73b 100644
--- a/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.tsx
+++ b/packages/@ourworldindata/grapher/src/slideInDrawer/SlideInDrawer.tsx
@@ -1,17 +1,15 @@
import React from "react"
-import cx from "classnames"
import { createPortal } from "react-dom"
import { computed, action, observable } from "mobx"
import { observer } from "mobx-react"
-import {
- GRAPHER_DRAWER_ID,
- GRAPHER_SCROLLABLE_CONTAINER_CLASS,
-} from "../core/GrapherConstants"
-import { CloseButton } from "../closeButton/CloseButton.js"
+import { GRAPHER_DRAWER_ID } from "../core/GrapherConstants"
+
+export const DrawerContext = React.createContext<{
+ toggleDrawerVisibility?: () => void
+}>({})
@observer
export class SlideInDrawer extends React.Component<{
- title: string
active: boolean
toggle: () => void
children: React.ReactNode
@@ -87,21 +85,13 @@ export class SlideInDrawer extends React.Component<{
...this.animationFor("grapher-drawer-contents"),
}}
>
-
-
- {this.props.title}
-
-
this.toggleVisibility()} />
-
-
-
{this.props.children}
-
+
)
diff --git a/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx b/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx
index 14d1225ea19..59c548c491d 100644
--- a/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx
+++ b/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx
@@ -35,7 +35,7 @@ import {
GRAPHER_FONT_SCALE_10_5,
GRAPHER_FONT_SCALE_11_2,
GRAPHER_TIMELINE_CLASS,
- GRAPHER_ENTITY_SELECTOR_CLASS,
+ GRAPHER_SIDE_PANEL_CLASS,
} from "../core/GrapherConstants"
import {
ScaleType,
@@ -536,7 +536,7 @@ export class SlopeChart
const target = e.target as HTMLElement
// check if the target is an interactive element or contained within one
- const selector = `a, button, input, .${GRAPHER_TIMELINE_CLASS}, .${GRAPHER_ENTITY_SELECTOR_CLASS}`
+ const selector = `a, button, input, .${GRAPHER_TIMELINE_CLASS}, .${GRAPHER_SIDE_PANEL_CLASS}`
const isTargetInteractive = target.closest(selector) !== null
if (