Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flyout: define position="inline" #500

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
34 changes: 34 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,40 @@ <h2 id="ethicalads">Ethical Ad</h2>
<h2 id="customscript">CustomScript</h2>
<p>Content of the section</p>

<h2 id="flyout">Flyout</h2>

<p>
Lorem ipsum odor amet, consectetuer adipiscing elit. Ultricies massa
molestie per iaculis id cras fermentum mi fames. Feugiat per cubilia
volutpat; dictumst cras libero fringilla.
</p>

<div style="width: 20em; height: 2.5em; background: red;">
<readthedocs-flyout position="up inline"></readthedocs-flyout>
</div>

<p>
Placerat conubia vivamus finibus
vulputate, sit ipsum. Senectus netus aptent laoreet per venenatis maximus.
Praesent mi tellus congue orci mus in etiam suspendisse. Inceptos senectus
nam accumsan, praesent felis consequat feugiat maximus. Dolor cras
faucibus sociosqu feugiat urna orci integer hendrerit.
</p>

<!-- Pretend this is a sidebar menu -->
<div style="width: 35em; position: fixed; left: 0; top: 100; background: red;">
<readthedocs-flyout position="down inline"></readthedocs-flyout>
</div>

<!-- Default positioning -->
<readthedocs-flyout position="bottom-right"></readthedocs-flyout>

<p>
Felis mus quis urna consequat arcu blandit finibus dui. Rutrum fames
aliquet nunc vitae aenean class mattis elit. Quis pretium himenaeos
facilisis sodales molestie fringilla ac interdum.
</p>

<h2 id="search">Search</h2>
<p>Hit <code>/</code> to trigger the search modal, or click on the input from the flyout.</p>
<readthedocs-search></readthedocs-search>
Expand Down
45 changes: 40 additions & 5 deletions src/flyout.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,38 @@
line-height: var(--addons-flyout-line-height);
}

.container.bottom-right {
.container.bottom-right:not(.inline) {
right: 20px;
bottom: 50px;
}

.container.bottom-left {
.container.bottom-left:not(.inline) {
left: 20px;
bottom: 50px;
}

.container.top-left {
.container.top-left:not(.inline) {
left: 20px;
top: 50px;
}

.container.top-right {
.container.top-right:not(.inline) {
right: 20px;
top: 50px;
}

.container.inline {
width: 100%;
max-width: 100%;
height: 100%;
max-height: 100%;
padding: 0 10px;
margin: 0;
position: relative;
display: inline-block;
overflow: visible;
}

:host > div {
font-family: var(
--readthedocs-flyout-font-family,
Expand Down Expand Up @@ -116,7 +128,30 @@ main {
margin-top: 5px;
}

main.closed {
.container.inline main {
position: absolute;
padding: 1em;
background-color: var(--readthedocs-flyout-background-color, rgb(39, 39, 37));

/* Remove the padding-left added in `.container.inline` */
margin-left: -10px;

/* Use full width minus 1em padding added on left and right in `.container.inline main` */
width: calc(100% - 2em);
}

.container.up.inline main {
top: unset;
bottom: 0;
}

.container.down.inline main {
top: 0;
bottom: unset;
}

main.closed,
.container.inline main.closed {
display: none;
}

Expand Down
27 changes: 24 additions & 3 deletions src/flyout.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export class FlyoutElement extends LitElement {
static properties = {
config: { state: true },
opened: { type: Boolean },
floating: { type: Boolean },
humitos marked this conversation as resolved.
Show resolved Hide resolved
position: { type: String },
};

Expand All @@ -37,7 +36,6 @@ export class FlyoutElement extends LitElement {

this.config = null;
this.opened = false;
this.floating = true;
this.position = "bottom-right";
this.readthedocsLogo = READTHEDOCS_LOGO;
}
Expand Down Expand Up @@ -327,10 +325,33 @@ export class FlyoutElement extends LitElement {
}

updateCSSClasses() {
this.classes = { floating: this.floating, container: true };
this.classes = { container: true };
this.classes[this.position] = true;
}

updated() {
// Update the `margin-bottom` property for the main part of the flyout,
// to display it exactly over the header of the flyout.
// I understand this is not possible to do with CSS, so we use JavaScript for it.
const main = this.renderRoot.querySelector("main");
const header = this.renderRoot.querySelector("header");
if (main !== null && header !== null) {
if (this.position.includes("up")) {
main.style.setProperty(
"margin-bottom",
`${header.getBoundingClientRect().height}px`,
);
}

if (this.position.includes("down")) {
main.style.setProperty(
"margin-top",
`${header.getBoundingClientRect().height}px`,
);
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we should always avoid doing anything with JS, especially with Element.style. What this property does is add inline style="" attribute to the element, which causes trouble with secure CSP rulesets and causes problems when users try to override our styles.

What value do we not know that we need to perform calculations in JS to get?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, but I did it in JS to show this is possible at least.

I wrote what I need to do in #500 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know how to do that with pure CSS? 🤔

Copy link
Contributor

@agjohnson agjohnson Jan 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In CSS this seems like it should just be addition. If we're mixing units, we should change them all to em so that the math is just a simple line-height + margin-bottom + margin-top + padding-bottom + padding-top. The header height should be static, we set the font size and don't allow wrapping, so there shouldn't be guessing there either.

What value do we not know that we need to perform calculations in JS to get?

This isn't clear to me still, so maybe I'm missing something here.


render() {
// The element doesn't yet have our config, don't render it.
if (this.config === null) {
Expand Down
4 changes: 2 additions & 2 deletions tests/__snapshots__/flyout.test.snap.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
export const snapshots = {};

snapshots["Flyout addon snapshot flyout completely"] =
`<div class="bottom-right container floating">
`<div class="bottom-right container">
<header>
<img
alt="Read the Docs"
Expand Down Expand Up @@ -121,7 +121,7 @@ snapshots["Flyout addon snapshot flyout completely"] =
/* end snapshot Flyout addon snapshot flyout completely */

snapshots["Flyout addon snapshot flyout with search disabled"] =
`<div class="bottom-right container floating">
`<div class="bottom-right container">
<header>
<img
alt="Read the Docs"
Expand Down