Skip to content

Commit ddbe6dc

Browse files
authored
Simplify DocNotebookDropdown positioning with float CSS (#651)
* Refactor DocNotebookDropdown component to use containerStyle for positioning and remove unnecessary resize logic. Update build_doc.py to insert the dropdown component after CopyLLMTxtMenu or before the first heading, enhancing layout control. Add tests to verify correct placement of the dropdown in various scenarios. * fix
1 parent dc21918 commit ddbe6dc

File tree

3 files changed

+66
-46
lines changed

3 files changed

+66
-46
lines changed

kit/src/lib/DocNotebookDropdown.svelte

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,20 @@
11
<script lang="ts">
2-
import { onMount, tick } from "svelte";
3-
42
import Dropdown from "./Dropdown.svelte";
53
import DropdownEntry from "./DropdownEntry.svelte";
64
75
export let options: { label: string; value: string }[] = [];
86
export let classNames = "";
9-
let dropdownEl: HTMLDivElement;
7+
export let containerStyle = "";
108
119
const googleColabOptions = options.filter((o) => o.value.includes("colab.research.google.com"));
1210
const awsStudioOptions = options.filter((o) => o.value.includes("studiolab.sagemaker.aws"));
1311
1412
function onClick(url: string) {
1513
window.open(url);
1614
}
17-
18-
function onResize() {
19-
// avoid DocNotebookDropdown overlapping with doc titles (i.e. h1 elements) on smaller screens because of absolute positioning
20-
const h1El = document.querySelector(".prose-doc h1");
21-
const h1SpanEl = document.querySelector(".prose-doc h1 > span");
22-
if (h1El && h1SpanEl) {
23-
const { width: h1Widht } = h1El.getBoundingClientRect();
24-
const { width: spanWidth } = h1SpanEl.getBoundingClientRect();
25-
// correct calculation of dropdownEl's width; othwrwise, the width can count in negative (empty) spaces
26-
let dropdownWidth = 0;
27-
for (let i = 0; i < dropdownEl.children.length; i++) {
28-
const child = dropdownEl.children.item(i);
29-
if (child) {
30-
dropdownWidth += child.clientWidth;
31-
}
32-
}
33-
const bufferMargin = 20;
34-
if (h1Widht - spanWidth < dropdownWidth + bufferMargin) {
35-
dropdownEl.classList.remove("absolute");
36-
} else {
37-
dropdownEl.classList.add("absolute");
38-
}
39-
}
40-
}
41-
42-
onMount(() => {
43-
(async () => {
44-
await tick();
45-
onResize();
46-
})();
47-
});
4815
</script>
4916

50-
<svelte:window on:resize={onResize} />
51-
52-
<div class="flex space-x-1 {classNames}" bind:this={dropdownEl}>
17+
<div class="flex space-x-1 {classNames}" style={containerStyle}>
5318
<slot name="alwaysVisible" />
5419
{#if googleColabOptions.length === 1}
5520
<a href={googleColabOptions[0].value} target="_blank">

src/doc_builder/build_doc.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
def resolve_open_in_colab(content, page_info):
3737
"""
3838
Replaces [[open-in-colab]] special markers by the proper svelte component.
39+
Places it after the CopyLLMTxtMenu so both buttons float on the heading line,
40+
with CopyLLMTxtMenu appearing rightmost.
3941
4042
Args:
4143
content (`str`): The documentation to treat.
@@ -61,13 +63,38 @@ def resolve_open_in_colab(content, page_info):
6163
formatted_links = [' {label: "' + key + '", value: "' + value + '"},' for key, value in links]
6264

6365
svelte_component = """<DocNotebookDropdown
64-
classNames="absolute z-10 right-0 top-0"
66+
containerStyle="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"
6567
options={[
6668
"""
6769
svelte_component += "\n".join(formatted_links)
68-
svelte_component += "\n]} />"
69-
70-
return content.replace("[[open-in-colab]]", svelte_component)
70+
svelte_component += "\n]} />\n\n"
71+
72+
# Remove the marker first
73+
content = content.replace("[[open-in-colab]]\n", "").replace("[[open-in-colab]]", "")
74+
75+
# Find CopyLLMTxtMenu and place DocNotebookDropdown right after it
76+
# With float:right, elements appear right-to-left, so placing after makes CopyLLMTxtMenu rightmost
77+
copy_menu_match = re.search(r"<CopyLLMTxtMenu\s+containerStyle=[^>]+></CopyLLMTxtMenu>", content)
78+
79+
if copy_menu_match:
80+
# Insert after CopyLLMTxtMenu (so Copy page appears rightmost when floated)
81+
insert_pos = copy_menu_match.end()
82+
# Remove any leading whitespace before CopyLLMTxtMenu and after it
83+
prefix = content[: copy_menu_match.start()].lstrip()
84+
suffix = content[insert_pos:].lstrip()
85+
# Add spacing: CopyLLMTxtMenu + newlines + DocNotebookDropdown (which already ends with \n\n) + suffix
86+
content = prefix + content[copy_menu_match.start() : insert_pos] + "\n\n" + svelte_component + suffix
87+
else:
88+
# No CopyLLMTxtMenu found, look for first heading and place before it
89+
heading_match = re.search(r"^#{1,2}\s+.+$", content, re.MULTILINE)
90+
if heading_match:
91+
insert_pos = heading_match.start()
92+
# Remove any leading whitespace before the component
93+
prefix = content[:insert_pos].lstrip()
94+
content = prefix + svelte_component + content[insert_pos:]
95+
# If no heading found either, the component just won't be added (marker already removed)
96+
97+
return content
7198

7299

73100
def resolve_autodoc(content, package, return_anchors=False, page_info=None, version_tag_suffix="src/"):

tests/test_build_doc.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,34 @@ def test_re_list_item(self):
2828
self.assertEqual(_re_list_item.search(" - forward").groups(), ("forward",))
2929

3030
def test_resolve_open_in_colab(self):
31-
expected = """
31+
# Test with heading - should place component before the heading
32+
input_with_heading = "[[open-in-colab]]\n\n# Quick tour\n\nSome content here."
33+
expected_with_heading = """<DocNotebookDropdown
34+
containerStyle="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"
35+
options={[
36+
{label: "Mixed", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/main/transformers_doc/en/quicktour.ipynb"},
37+
{label: "PyTorch", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/main/transformers_doc/en/pytorch/quicktour.ipynb"},
38+
{label: "TensorFlow", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/main/transformers_doc/en/tensorflow/quicktour.ipynb"},
39+
{label: "Mixed", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/transformers_doc/en/quicktour.ipynb"},
40+
{label: "PyTorch", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/transformers_doc/en/pytorch/quicktour.ipynb"},
41+
{label: "TensorFlow", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/transformers_doc/en/tensorflow/quicktour.ipynb"},
42+
]} />
43+
44+
# Quick tour
45+
46+
Some content here."""
47+
self.assertEqual(
48+
resolve_open_in_colab(input_with_heading, {"package_name": "transformers", "page": "quicktour.html"}),
49+
expected_with_heading,
50+
)
51+
52+
# Test with CopyLLMTxtMenu present - should place component after CopyLLMTxtMenu
53+
# (so CopyLLMTxtMenu appears rightmost when floated)
54+
input_with_copy_menu = '[[open-in-colab]]\n\n<CopyLLMTxtMenu containerStyle="float: right;"></CopyLLMTxtMenu>\n\n# Quick tour\n\nContent.'
55+
expected_with_copy_menu = """<CopyLLMTxtMenu containerStyle="float: right;"></CopyLLMTxtMenu>
56+
3257
<DocNotebookDropdown
33-
classNames="absolute z-10 right-0 top-0"
58+
containerStyle="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"
3459
options={[
3560
{label: "Mixed", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/main/transformers_doc/en/quicktour.ipynb"},
3661
{label: "PyTorch", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/main/transformers_doc/en/pytorch/quicktour.ipynb"},
@@ -39,8 +64,11 @@ def test_resolve_open_in_colab(self):
3964
{label: "PyTorch", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/transformers_doc/en/pytorch/quicktour.ipynb"},
4065
{label: "TensorFlow", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/main/transformers_doc/en/tensorflow/quicktour.ipynb"},
4166
]} />
42-
"""
67+
68+
# Quick tour
69+
70+
Content."""
4371
self.assertEqual(
44-
resolve_open_in_colab("\n[[open-in-colab]]\n", {"package_name": "transformers", "page": "quicktour.html"}),
45-
expected,
72+
resolve_open_in_colab(input_with_copy_menu, {"package_name": "transformers", "page": "quicktour.html"}),
73+
expected_with_copy_menu,
4674
)

0 commit comments

Comments
 (0)