mkdocs-pixel-lab 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/PKG-INFO +1 -1
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/details.md +70 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/pyproject.toml +1 -1
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/css/style.css +36 -1
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/js/main.js +19 -7
- mkdocs_pixel_lab-0.2.2/tests/fixture_site/docs/guide/details.md +231 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/mkdocs.yml +1 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_theme.py +201 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/.gitignore +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/LICENSE +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/README.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/THIRD_PARTY_LICENSES.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/assets/component-preview.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/admonitions.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/alerts.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/code-blocks.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/index.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/media.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/metadata.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/tables.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/tabs.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/components/text.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/getting-started.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/index.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/reference/compatibility.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/reference/configuration.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/reference/plugins.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/reference/troubleshooting.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/reference/upgrading.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/analytics.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/branding.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/colors.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/fonts.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/heading-permalinks.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/icons.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/index.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/navigation.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/page-actions.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/related-sites.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/repository.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/docs/setup/search.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/mkdocs.yml +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/__init__.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/analytics.html +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/css/analytics.css +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/favicon.png +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/fonts/ibm-plex-mono-400.woff2 +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/fonts/ibm-plex-mono-600.woff2 +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/fonts/ibm-plex-mono-700.woff2 +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/fonts/inter-latin.woff2 +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/heading-link.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/page-edit.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/page-source.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/repository.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/search.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/js/analytics.js +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/base.html +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/git_lastmod.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/github_alerts.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/icons.html +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/main.html +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/metadata.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/mkdocs_theme.yml +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/page_source.html +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/robots.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/site_navigation.html +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/sitemap.xml +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/assets/alignment-wide.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/assets/pixel-lab-demo.mp4 +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/assets/pixel-lab-preview.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/assets/site-navigation-hover.svg +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/guide/alignment.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/guide/code.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/guide/media.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/guide/nested.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/guide/tabs.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/index.md +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/snapshots/desktop.png +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/snapshots/mobile.png +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_analytics.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_docs_workflow.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_documentation.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_git_lastmod.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_icons.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_metadata.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_permalinks.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_privacy.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_repository.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_robots.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_site_navigation.py +0 -0
- {mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/test_source_links.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: mkdocs-pixel-lab
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A vibrant, accessible MkDocs documentation theme by Trained-by-Humans.
|
|
5
5
|
Project-URL: Homepage, https://github.com/trained-by-humans/mkdocs-pixel-lab
|
|
6
6
|
Project-URL: Documentation, https://github.com/trained-by-humans/mkdocs-pixel-lab#readme
|
|
@@ -62,6 +62,76 @@ This body supports **Markdown**.
|
|
|
62
62
|
</details>
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
## Layout modes
|
|
66
|
+
|
|
67
|
+
Pixel Lab chooses each expanded body's layout automatically, like
|
|
68
|
+
[content tabs](tabs.md#layout-modes):
|
|
69
|
+
|
|
70
|
+
- A single [code block](code-blocks.md) or [table](tables.md) fills the body **flush**.
|
|
71
|
+
- Prose, multiple blocks, and mixed content use a **padded** inset.
|
|
72
|
+
- Nested details and tabs select their layouts independently.
|
|
73
|
+
|
|
74
|
+
Flush content shares the details frame without a duplicate border or surrounding
|
|
75
|
+
gap. Code retains its internal padding, and wide code and tables scroll
|
|
76
|
+
horizontally inside the body.
|
|
77
|
+
|
|
78
|
+
???+ note "Code without an extra inset"
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
print("One code block fills the expanded body")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
???+ note "A table without an extra inset"
|
|
85
|
+
|
|
86
|
+
| Content | Layout |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| Single code block or table | Flush |
|
|
89
|
+
| Prose or mixed content | Padded |
|
|
90
|
+
|
|
91
|
+
### Scoped layout overrides
|
|
92
|
+
|
|
93
|
+
Use `.details-padded` or `.details-flush` directly on a native `<details>`
|
|
94
|
+
element, or wrap selected `???` blocks using
|
|
95
|
+
[Scope selected instances](index.md#scope-selected-instances):
|
|
96
|
+
|
|
97
|
+
<div class="details-padded" markdown="1">
|
|
98
|
+
|
|
99
|
+
???+ note "Always padded"
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
print("Keep an inset around this block")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
````markdown
|
|
108
|
+
<div class="details-padded" markdown="1">
|
|
109
|
+
|
|
110
|
+
???+ note "Always padded"
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
print("Keep an inset around this block")
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
</div>
|
|
117
|
+
````
|
|
118
|
+
|
|
119
|
+
For native HTML, place the class on the element:
|
|
120
|
+
|
|
121
|
+
```html
|
|
122
|
+
<details class="details-flush" open>
|
|
123
|
+
<summary>Always flush</summary>
|
|
124
|
+
<pre><code>Keep code's internal padding.</code></pre>
|
|
125
|
+
</details>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
> [!NOTE]
|
|
129
|
+
>
|
|
130
|
+
> - For nested details, the nearest details layout class controls the layout.
|
|
131
|
+
> - These classes affect only details; `.tabs-padded` and `.tabs-flush` affect only tabs.
|
|
132
|
+
> - `.details-padded` and `.details-flush` work with or without JavaScript.
|
|
133
|
+
> - Automatic layout requires JavaScript, without it details stay padded.
|
|
134
|
+
|
|
65
135
|
## Customization
|
|
66
136
|
|
|
67
137
|
These theme settings customize all collapsible blocks. Different detail types
|
|
@@ -563,12 +563,47 @@ img, video {
|
|
|
563
563
|
padding: 8px 12px;
|
|
564
564
|
text-transform: uppercase;
|
|
565
565
|
}
|
|
566
|
-
.admonition > :not(.admonition-title)
|
|
566
|
+
.admonition > :not(.admonition-title) {
|
|
567
567
|
margin-left: 14px;
|
|
568
568
|
margin-right: 14px;
|
|
569
569
|
max-width: calc(100% - 28px);
|
|
570
570
|
}
|
|
571
571
|
.admonition-title + p { padding-bottom: 14px; }
|
|
572
|
+
/* Details are padded by default. Explicit classes inherit through wrappers;
|
|
573
|
+
JavaScript marks automatic layouts on the details element itself. */
|
|
574
|
+
.details-padded,
|
|
575
|
+
:where(details[data-details-layout="padded"]) {
|
|
576
|
+
--details-padding: 14px;
|
|
577
|
+
--details-inner-border: 2px;
|
|
578
|
+
--details-table-width: fit-content;
|
|
579
|
+
--details-cell-border: 1px;
|
|
580
|
+
}
|
|
581
|
+
.details-flush,
|
|
582
|
+
:where(details[data-details-layout="flush"]) {
|
|
583
|
+
--details-padding: 0px;
|
|
584
|
+
--details-inner-border: 0px;
|
|
585
|
+
--details-table-width: 100%;
|
|
586
|
+
--details-cell-border: 0px;
|
|
587
|
+
}
|
|
588
|
+
details { padding: 0 var(--details-padding, 14px) var(--details-padding, 14px); }
|
|
589
|
+
details > summary { margin: 0 calc(-1 * var(--details-padding, 14px)) var(--details-padding, 14px); }
|
|
590
|
+
details:not([open]) { padding-bottom: 0; }
|
|
591
|
+
details:not([open]) > summary { margin-bottom: 0; }
|
|
592
|
+
details > :not(summary) { margin-left: 0; margin-right: 0; max-width: 100%; }
|
|
593
|
+
details > pre,
|
|
594
|
+
details > .highlight > pre { border-width: var(--details-inner-border, 2px); max-width: 100%; }
|
|
595
|
+
details[open] > summary + *,
|
|
596
|
+
details > summary + .highlight > pre { margin-top: 0; }
|
|
597
|
+
details > :last-child:not(summary),
|
|
598
|
+
details > .highlight:last-child > pre { margin-bottom: 0; }
|
|
599
|
+
details > table { display: block; overflow-x: auto; }
|
|
600
|
+
details > .table-shell { max-width: 100%; width: var(--details-table-width, fit-content); }
|
|
601
|
+
details > .table-shell > .table-scroll { border-width: var(--details-inner-border, 2px); }
|
|
602
|
+
details > .table-shell > .table-scroll > table { min-width: 100%; }
|
|
603
|
+
:is(details > table, details > .table-shell > .table-scroll > table) > :first-child > tr:first-child > * { border-top-width: var(--details-cell-border, 1px); }
|
|
604
|
+
:is(details > table, details > .table-shell > .table-scroll > table) > :last-child > tr:last-child > * { border-bottom-width: var(--details-cell-border, 1px); }
|
|
605
|
+
:is(details > table, details > .table-shell > .table-scroll > table) > * > tr > :first-child { border-left-width: var(--details-cell-border, 1px); }
|
|
606
|
+
:is(details > table, details > .table-shell > .table-scroll > table) > * > tr > :last-child { border-right-width: var(--details-cell-border, 1px); }
|
|
572
607
|
|
|
573
608
|
.tabbed-set {
|
|
574
609
|
background: var(--surface);
|
|
@@ -347,19 +347,31 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
347
347
|
scroll.appendChild(table);
|
|
348
348
|
});
|
|
349
349
|
|
|
350
|
-
// Classify direct
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
const content =
|
|
350
|
+
// Classify direct content after tables receive their scrolling wrappers.
|
|
351
|
+
const contentLayout = (panel, override = null, flushClass = "tabs-flush") => {
|
|
352
|
+
const children = Array.from(panel.children).filter((child) => !child.matches("summary"));
|
|
353
|
+
const content = children[0];
|
|
354
354
|
const hasText = Array.from(panel.childNodes).some(
|
|
355
355
|
(node) => node.nodeType === Node.TEXT_NODE && node.textContent.trim(),
|
|
356
356
|
);
|
|
357
|
-
const singleBlock =
|
|
357
|
+
const singleBlock = children.length === 1 && !hasText && content && (
|
|
358
358
|
content.matches("pre, .table-shell") ||
|
|
359
359
|
(content.matches(".highlight") && content.querySelector("pre"))
|
|
360
360
|
);
|
|
361
|
-
const flush = override ? override.classList.contains(
|
|
362
|
-
|
|
361
|
+
const flush = override ? override.classList.contains(flushClass) : singleBlock;
|
|
362
|
+
return flush ? "flush" : "padded";
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
document.querySelectorAll(".tabbed-content > .tabbed-block").forEach((panel) => {
|
|
366
|
+
panel.dataset.tabLayout = contentLayout(
|
|
367
|
+
panel, panel.closest(".tabs-padded, .tabs-flush"), "tabs-flush",
|
|
368
|
+
);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
document.querySelectorAll(".main details").forEach((details) => {
|
|
372
|
+
// Explicit classes are handled by CSS, with or without JavaScript.
|
|
373
|
+
if (details.closest(".details-padded, .details-flush")) return;
|
|
374
|
+
details.dataset.detailsLayout = contentLayout(details);
|
|
363
375
|
});
|
|
364
376
|
|
|
365
377
|
document.querySelectorAll(".tabs-demo").forEach((group) => {
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Details layouts
|
|
2
|
+
|
|
3
|
+
## Pymdown details
|
|
4
|
+
|
|
5
|
+
<!-- Minimal reproduction of the code-only expand at:
|
|
6
|
+
https://ultralytics.ml-pipes.com/tutorials/isolate_segmented_objects/ -->
|
|
7
|
+
<div id="pym-code" markdown="1">
|
|
8
|
+
|
|
9
|
+
??? note "Define the IsolateObjects operator"
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
def isolate_objects(image, masks):
|
|
13
|
+
return [image * mask for mask in masks] # A long line exercises scrolling without widening the expandable frame.
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div id="pym-table" markdown="1">
|
|
19
|
+
|
|
20
|
+
???+ tip "Table, initially open"
|
|
21
|
+
|
|
22
|
+
| Payload | Result |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| `a_very_long_unbroken_payload_name_to_exercise_horizontal_scrolling_in_a_narrow_details_body` | Isolated object |
|
|
25
|
+
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div id="pym-prose" markdown="1">
|
|
29
|
+
|
|
30
|
+
???+ note "Prose"
|
|
31
|
+
|
|
32
|
+
Keep a comfortable inset for explanations.
|
|
33
|
+
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div id="pym-mixed" markdown="1">
|
|
37
|
+
|
|
38
|
+
???+ note "Mixed content"
|
|
39
|
+
|
|
40
|
+
Explanation before code.
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
print("Mixed content stays padded")
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div id="pym-multiple" markdown="1">
|
|
49
|
+
|
|
50
|
+
???+ note "Multiple blocks"
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
First block
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Second block
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
## Native HTML
|
|
63
|
+
|
|
64
|
+
<details id="raw-code" open>
|
|
65
|
+
<summary>Raw code</summary>
|
|
66
|
+
<!-- Comments and whitespace do not count as content blocks. -->
|
|
67
|
+
<pre><code>A long raw code line exercises horizontal scrolling without widening the expandable frame or losing its internal code padding.</code></pre>
|
|
68
|
+
</details>
|
|
69
|
+
|
|
70
|
+
<details id="raw-table">
|
|
71
|
+
<summary>Raw table</summary>
|
|
72
|
+
<table><thead><tr><th>Payload</th><th>Result</th></tr></thead>
|
|
73
|
+
<tbody><tr><td>a_very_long_unbroken_payload_name_to_exercise_horizontal_scrolling_in_a_narrow_details_body</td><td>Isolated object</td></tr></tbody></table>
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
<details id="raw-prose" open>
|
|
77
|
+
<summary>Raw prose</summary>
|
|
78
|
+
<p>Keep a comfortable inset for explanations.</p>
|
|
79
|
+
</details>
|
|
80
|
+
|
|
81
|
+
<details id="raw-mixed" open>
|
|
82
|
+
<summary>Raw mixed content</summary>
|
|
83
|
+
<p>Explanation before code.</p>
|
|
84
|
+
<pre><code>Mixed content stays padded.</code></pre>
|
|
85
|
+
</details>
|
|
86
|
+
|
|
87
|
+
<details id="raw-multiple" open>
|
|
88
|
+
<summary>Raw multiple blocks</summary>
|
|
89
|
+
<pre><code>First block</code></pre>
|
|
90
|
+
<pre><code>Second block</code></pre>
|
|
91
|
+
</details>
|
|
92
|
+
|
|
93
|
+
<details id="raw-text" open>
|
|
94
|
+
<summary>Text nodes also count</summary>
|
|
95
|
+
An unwrapped explanation.
|
|
96
|
+
<pre><code>One element with a text sibling stays padded.</code></pre>
|
|
97
|
+
</details>
|
|
98
|
+
|
|
99
|
+
## Explicit overrides
|
|
100
|
+
|
|
101
|
+
<div id="pym-padded-code" class="details-padded" markdown="1">
|
|
102
|
+
|
|
103
|
+
???+ note "Padded code"
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
print("Explicit inset")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<div id="pym-padded-table" class="details-padded" markdown="1">
|
|
112
|
+
|
|
113
|
+
???+ note "Padded table"
|
|
114
|
+
|
|
115
|
+
| Setting | Value |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| Inset | Padded |
|
|
118
|
+
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div id="pym-flush-mixed" class="details-flush" markdown="1">
|
|
122
|
+
|
|
123
|
+
???+ note "Flush mixed content"
|
|
124
|
+
|
|
125
|
+
Explicitly remove the surrounding inset.
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
print("Still keep internal code padding")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<details id="raw-padded-code" class="details-padded" open>
|
|
134
|
+
<summary>Raw padded code</summary>
|
|
135
|
+
<pre><code>Explicit inset</code></pre>
|
|
136
|
+
</details>
|
|
137
|
+
|
|
138
|
+
<details id="raw-padded-table" class="details-padded" open>
|
|
139
|
+
<summary>Raw padded table</summary>
|
|
140
|
+
<table><tr><th>Setting</th><th>Value</th></tr><tr><td>Inset</td><td>Padded</td></tr></table>
|
|
141
|
+
</details>
|
|
142
|
+
|
|
143
|
+
<details id="raw-flush-mixed" class="details-flush" open>
|
|
144
|
+
<summary>Raw flush mixed content</summary>
|
|
145
|
+
<p>Explicitly remove the surrounding inset.</p>
|
|
146
|
+
<pre><code>Still keep internal code padding</code></pre>
|
|
147
|
+
</details>
|
|
148
|
+
|
|
149
|
+
<div id="pym-flush-code" class="details-flush" markdown="1">
|
|
150
|
+
|
|
151
|
+
???+ note "Flush code without JavaScript"
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
print("A long code line scrolls horizontally while the explicit flush layout keeps its internal code padding intact.")
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<div id="pym-flush-table" class="details-flush" markdown="1">
|
|
160
|
+
|
|
161
|
+
???+ note "Flush table without JavaScript"
|
|
162
|
+
|
|
163
|
+
| Payload | Result |
|
|
164
|
+
| --- | --- |
|
|
165
|
+
| `a_very_long_unbroken_payload_name_to_exercise_horizontal_scrolling_in_a_narrow_details_body` | Isolated object |
|
|
166
|
+
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<details id="raw-flush-code" class="details-flush" open>
|
|
170
|
+
<summary>Raw flush code without JavaScript</summary>
|
|
171
|
+
<pre><code>A long code line scrolls horizontally while the explicit flush layout keeps its internal code padding intact.</code></pre>
|
|
172
|
+
</details>
|
|
173
|
+
|
|
174
|
+
<details id="raw-flush-table" class="details-flush" open>
|
|
175
|
+
<summary>Raw flush table without JavaScript</summary>
|
|
176
|
+
<table><thead><tr><th>Payload</th><th>Result</th></tr></thead>
|
|
177
|
+
<tbody><tr><td>a_very_long_unbroken_payload_name_to_exercise_horizontal_scrolling_in_a_narrow_details_body</td><td>Isolated object</td></tr></tbody></table>
|
|
178
|
+
</details>
|
|
179
|
+
|
|
180
|
+
## Nested details and tabs
|
|
181
|
+
|
|
182
|
+
<div class="details-padded" markdown="1">
|
|
183
|
+
|
|
184
|
+
<details id="nested-outer" class="details-flush" open markdown="1">
|
|
185
|
+
<summary>Closest override wins</summary>
|
|
186
|
+
|
|
187
|
+
<details id="nested-inner" class="details-padded" open markdown="1">
|
|
188
|
+
<summary>Inner details override</summary>
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
print("Inner details are padded")
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
</details>
|
|
195
|
+
|
|
196
|
+
<details id="nested-inherited" open>
|
|
197
|
+
<summary>Inherit the closest wrapper</summary>
|
|
198
|
+
<pre><code>Inherit flush from the outer details</code></pre>
|
|
199
|
+
</details>
|
|
200
|
+
|
|
201
|
+
=== "Independent tabs"
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
print("Tabs automatically select flush despite details overrides")
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
</details>
|
|
208
|
+
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<details id="automatic-outer" open>
|
|
212
|
+
<summary>Automatic nested details</summary>
|
|
213
|
+
<details id="automatic-inner" open>
|
|
214
|
+
<summary>Inner code</summary>
|
|
215
|
+
<pre><code>Only the inner details automatically become flush.</code></pre>
|
|
216
|
+
</details>
|
|
217
|
+
</details>
|
|
218
|
+
|
|
219
|
+
<div id="details-in-tabs" class="tabs-flush" markdown="1">
|
|
220
|
+
|
|
221
|
+
=== "Independent details"
|
|
222
|
+
|
|
223
|
+
???+ note "Details still choose padded"
|
|
224
|
+
|
|
225
|
+
A tab override does not change the details layout.
|
|
226
|
+
|
|
227
|
+
```text
|
|
228
|
+
Mixed content stays padded.
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
</div>
|
|
@@ -651,6 +651,207 @@ def test_tabs_keep_padded_fallback_without_javascript(browser, site_url: str) ->
|
|
|
651
651
|
context.close()
|
|
652
652
|
|
|
653
653
|
|
|
654
|
+
@pytest.mark.parametrize("width", [1440, 390, 320])
|
|
655
|
+
def test_details_content_layouts(page, site_url: str, width: int) -> None:
|
|
656
|
+
page.set_viewport_size({"width": width, "height": 900})
|
|
657
|
+
page.goto(f"{site_url}/guide/details/")
|
|
658
|
+
page.evaluate("document.fonts.ready")
|
|
659
|
+
page.add_style_tag(content="html { scroll-behavior: auto; }")
|
|
660
|
+
expect(page.locator("#pym-code > details")).not_to_have_attribute("open")
|
|
661
|
+
expect(page.locator("#pym-table > details")).to_have_attribute("open", "open")
|
|
662
|
+
expect(page.locator("#raw-code")).to_have_attribute("open", "")
|
|
663
|
+
expect(page.locator("#raw-table")).not_to_have_attribute("open")
|
|
664
|
+
expect(page.locator(".details-content")).to_have_count(0)
|
|
665
|
+
for source in ("pym", "raw"):
|
|
666
|
+
for kind, layout in (("code", "flush"), ("table", "flush"), ("prose", "padded"),
|
|
667
|
+
("mixed", "padded"), ("multiple", "padded"),
|
|
668
|
+
("padded-code", "padded"), ("padded-table", "padded"),
|
|
669
|
+
("flush-mixed", "flush"), ("flush-code", "flush"), ("flush-table", "flush")):
|
|
670
|
+
fixture = page.locator(f"#{source}-{kind}")
|
|
671
|
+
details = fixture if source == "raw" else fixture.locator(":scope > details")
|
|
672
|
+
summary = details.locator(":scope > summary")
|
|
673
|
+
if details.get_attribute("open") is None:
|
|
674
|
+
summary.click()
|
|
675
|
+
content = details.locator(":scope > :not(summary)")
|
|
676
|
+
expect(content.first).to_be_visible()
|
|
677
|
+
if "-" not in kind:
|
|
678
|
+
expect(details).to_have_attribute("data-details-layout", layout)
|
|
679
|
+
else:
|
|
680
|
+
expect(details).not_to_have_attribute("data-details-layout")
|
|
681
|
+
inset = 0 if layout == "flush" else 14
|
|
682
|
+
expect(details).to_have_css("padding-left", f"{inset}px")
|
|
683
|
+
expect(details).to_have_css("padding-bottom", f"{inset}px")
|
|
684
|
+
outer = details.bounding_box()
|
|
685
|
+
summary_bounds = summary.bounding_box()
|
|
686
|
+
first = content.first.bounding_box()
|
|
687
|
+
last = content.last.bounding_box()
|
|
688
|
+
assert summary_bounds["x"] == pytest.approx(outer["x"] + 2)
|
|
689
|
+
assert summary_bounds["width"] == pytest.approx(outer["width"] - 4)
|
|
690
|
+
assert first["x"] == pytest.approx(outer["x"] + 2 + inset)
|
|
691
|
+
assert first["y"] == pytest.approx(summary_bounds["y"] + summary_bounds["height"] + inset)
|
|
692
|
+
assert last["y"] + last["height"] == pytest.approx(outer["y"] + outer["height"] - 2 - inset)
|
|
693
|
+
for pre in details.locator("pre").all():
|
|
694
|
+
expect(pre).to_have_css("padding-left", "20px")
|
|
695
|
+
expect(pre).to_have_css("box-shadow", "none")
|
|
696
|
+
if layout == "flush":
|
|
697
|
+
expect(pre).to_have_css("border-left-width", "0px")
|
|
698
|
+
assert pre.bounding_box()["width"] == pytest.approx(outer["width"] - 4)
|
|
699
|
+
if kind in ("code", "table"):
|
|
700
|
+
scroll = details.locator("pre" if kind == "code" else ".table-scroll")
|
|
701
|
+
expect(scroll).to_have_css("border-top-width", "0px")
|
|
702
|
+
expect(scroll).to_have_css("border-bottom-width", "0px")
|
|
703
|
+
expect(scroll).to_have_css("box-shadow", "none")
|
|
704
|
+
assert scroll.bounding_box()["width"] == pytest.approx(outer["width"] - 4)
|
|
705
|
+
if width < 400:
|
|
706
|
+
assert scroll.evaluate("el => el.scrollWidth > el.clientWidth")
|
|
707
|
+
scroll.evaluate("el => el.scrollLeft = 60")
|
|
708
|
+
assert scroll.evaluate("el => el.scrollLeft") > 0
|
|
709
|
+
if kind == "table":
|
|
710
|
+
cells = details.locator("tr").first.locator("th")
|
|
711
|
+
expect(cells.first).to_have_css("border-top-width", "0px")
|
|
712
|
+
expect(cells.first).to_have_css("border-left-width", "0px")
|
|
713
|
+
expect(cells.last).to_have_css("border-right-width", "0px")
|
|
714
|
+
elif source == "pym":
|
|
715
|
+
button = details.get_by_role("button", name="Copy code to clipboard")
|
|
716
|
+
expect(button).to_be_visible()
|
|
717
|
+
summary.focus()
|
|
718
|
+
summary.press("Enter")
|
|
719
|
+
expect(details).not_to_have_attribute("open")
|
|
720
|
+
expect(content.first).not_to_be_visible()
|
|
721
|
+
summary.press("Space")
|
|
722
|
+
expect(details).to_have_attribute("open", "")
|
|
723
|
+
expect(content.first).to_be_visible()
|
|
724
|
+
expect(page.locator("#raw-text")).to_have_attribute("data-details-layout", "padded")
|
|
725
|
+
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
@pytest.mark.parametrize("width", [1440, 320])
|
|
729
|
+
def test_details_nested_layouts_and_overrides(page, site_url: str, width: int) -> None:
|
|
730
|
+
page.set_viewport_size({"width": width, "height": 900})
|
|
731
|
+
page.goto(f"{site_url}/guide/details/")
|
|
732
|
+
page.evaluate("document.fonts.ready")
|
|
733
|
+
page.add_style_tag(content="html { scroll-behavior: auto; }")
|
|
734
|
+
for identifier, layout in (("nested-outer", "flush"), ("nested-inner", "padded"),
|
|
735
|
+
("nested-inherited", "flush"), ("automatic-outer", "padded"),
|
|
736
|
+
("automatic-inner", "flush")):
|
|
737
|
+
details = page.locator(f"#{identifier}")
|
|
738
|
+
if identifier.startswith("automatic-"):
|
|
739
|
+
expect(details).to_have_attribute("data-details-layout", layout)
|
|
740
|
+
else:
|
|
741
|
+
expect(details).not_to_have_attribute("data-details-layout")
|
|
742
|
+
expect(details).to_have_css("padding-left", "0px" if layout == "flush" else "14px")
|
|
743
|
+
if identifier not in ("nested-outer", "automatic-outer"):
|
|
744
|
+
expect(details).to_have_css("box-shadow", "none")
|
|
745
|
+
tabs = page.locator("#nested-outer .tabbed-block")
|
|
746
|
+
expect(tabs).to_have_attribute("data-tab-layout", "flush")
|
|
747
|
+
expect(tabs).to_have_css("padding-left", "0px")
|
|
748
|
+
expect(page.locator("#details-in-tabs .tabbed-block")).to_have_attribute("data-tab-layout", "flush")
|
|
749
|
+
expect(page.locator("#details-in-tabs details")).to_have_css("padding-left", "14px")
|
|
750
|
+
outer_summary = page.locator("#automatic-outer > summary")
|
|
751
|
+
outer_summary.click()
|
|
752
|
+
expect(page.locator("#automatic-inner > pre")).not_to_be_visible()
|
|
753
|
+
outer_summary.click()
|
|
754
|
+
expect(page.locator("#automatic-inner > pre")).to_be_visible()
|
|
755
|
+
# An explicit class also takes precedence over an existing automatic marker.
|
|
756
|
+
automatic = page.locator("#pym-code > details")
|
|
757
|
+
automatic.evaluate("el => el.classList.add('details-padded')")
|
|
758
|
+
expect(automatic).to_have_css("padding-left", "14px")
|
|
759
|
+
expect(automatic.locator("pre")).to_have_css("border-left-width", "2px")
|
|
760
|
+
automatic.evaluate("el => el.classList.remove('details-padded')")
|
|
761
|
+
expect(automatic).to_have_css("padding-left", "0px")
|
|
762
|
+
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
@pytest.mark.parametrize("width", [1440, 320])
|
|
766
|
+
def test_details_keep_native_padded_fallback_without_javascript(browser, site_url: str, width: int) -> None:
|
|
767
|
+
context = browser.new_context(java_script_enabled=False, viewport={"width": width, "height": 900})
|
|
768
|
+
try:
|
|
769
|
+
page = context.new_page()
|
|
770
|
+
page.goto(f"{site_url}/guide/details/")
|
|
771
|
+
page.evaluate("document.documentElement.style.scrollBehavior = 'auto'")
|
|
772
|
+
for selector in ("#pym-code > details", "#raw-code", "#pym-table > details", "#raw-table",
|
|
773
|
+
"#pym-padded-code > details", "#raw-padded-code"):
|
|
774
|
+
details = page.locator(selector)
|
|
775
|
+
summary = details.locator(":scope > summary")
|
|
776
|
+
if details.get_attribute("open") is None:
|
|
777
|
+
summary.click()
|
|
778
|
+
content = details.locator(":scope > :not(summary)").first
|
|
779
|
+
expect(content).to_be_visible()
|
|
780
|
+
assert content.bounding_box()["x"] == pytest.approx(details.bounding_box()["x"] + 16)
|
|
781
|
+
assert content.bounding_box()["y"] > summary.bounding_box()["y"] + summary.bounding_box()["height"]
|
|
782
|
+
if width == 320 and selector in ("#pym-code > details", "#raw-code", "#raw-table"):
|
|
783
|
+
scroll = details.locator("pre" if "code" in selector else "table")
|
|
784
|
+
assert scroll.evaluate("el => el.scrollWidth > el.clientWidth")
|
|
785
|
+
scroll.evaluate("el => el.scrollLeft = 60")
|
|
786
|
+
assert scroll.evaluate("el => el.scrollLeft") > 0
|
|
787
|
+
summary.focus()
|
|
788
|
+
summary.press("Enter")
|
|
789
|
+
expect(content).not_to_be_visible()
|
|
790
|
+
summary.press("Space")
|
|
791
|
+
expect(content).to_be_visible()
|
|
792
|
+
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
|
|
793
|
+
finally:
|
|
794
|
+
context.close()
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
@pytest.mark.parametrize("width", [1440, 320])
|
|
798
|
+
def test_details_explicit_layouts_without_javascript(browser, site_url: str, width: int) -> None:
|
|
799
|
+
context = browser.new_context(java_script_enabled=False, viewport={"width": width, "height": 900})
|
|
800
|
+
try:
|
|
801
|
+
page = context.new_page()
|
|
802
|
+
page.goto(f"{site_url}/guide/details/")
|
|
803
|
+
page.evaluate("document.documentElement.style.scrollBehavior = 'auto'")
|
|
804
|
+
for source in ("pym", "raw"):
|
|
805
|
+
for kind, inset in (("padded-code", 14), ("padded-table", 14),
|
|
806
|
+
("flush-code", 0), ("flush-table", 0), ("flush-mixed", 0)):
|
|
807
|
+
fixture = page.locator(f"#{source}-{kind}")
|
|
808
|
+
details = fixture if source == "raw" else fixture.locator(":scope > details")
|
|
809
|
+
content = details.locator(":scope > :not(summary)").first
|
|
810
|
+
bounds = details.bounding_box()
|
|
811
|
+
assert content.bounding_box()["x"] == pytest.approx(bounds["x"] + 2 + inset)
|
|
812
|
+
summary = details.locator(":scope > summary")
|
|
813
|
+
summary_bounds = summary.bounding_box()
|
|
814
|
+
assert content.bounding_box()["y"] == pytest.approx(
|
|
815
|
+
summary_bounds["y"] + summary_bounds["height"] + inset,
|
|
816
|
+
)
|
|
817
|
+
last = details.locator(":scope > :not(summary)").last
|
|
818
|
+
last_bounds = last.bounding_box()
|
|
819
|
+
assert last_bounds["y"] + last_bounds["height"] == pytest.approx(
|
|
820
|
+
bounds["y"] + bounds["height"] - 2 - inset,
|
|
821
|
+
)
|
|
822
|
+
for pre in details.locator("pre").all():
|
|
823
|
+
expect(pre).to_have_css("padding-left", "20px")
|
|
824
|
+
expect(pre).to_have_css("border-top-width", "2px" if inset else "0px")
|
|
825
|
+
expect(pre).to_have_css("box-shadow", "none")
|
|
826
|
+
if kind in ("flush-code", "flush-table"):
|
|
827
|
+
scroll = details.locator("pre" if kind == "flush-code" else "table")
|
|
828
|
+
assert scroll.bounding_box()["width"] == pytest.approx(bounds["width"] - 4)
|
|
829
|
+
if width == 320:
|
|
830
|
+
assert scroll.evaluate("el => el.scrollWidth > el.clientWidth")
|
|
831
|
+
scroll.evaluate("el => el.scrollLeft = 60")
|
|
832
|
+
assert scroll.evaluate("el => el.scrollLeft") > 0
|
|
833
|
+
if kind == "flush-table":
|
|
834
|
+
cells = details.locator("tr").first.locator("th")
|
|
835
|
+
expect(cells.first).to_have_css("border-top-width", "0px")
|
|
836
|
+
expect(cells.first).to_have_css("border-left-width", "0px")
|
|
837
|
+
expect(cells.last).to_have_css("border-right-width", "0px")
|
|
838
|
+
summary = details.locator(":scope > summary")
|
|
839
|
+
summary.focus()
|
|
840
|
+
summary.press("Enter")
|
|
841
|
+
expect(content).not_to_be_visible()
|
|
842
|
+
summary.press("Space")
|
|
843
|
+
expect(content).to_be_visible()
|
|
844
|
+
for identifier, inset in (("nested-outer", 0), ("nested-inner", 14), ("nested-inherited", 0)):
|
|
845
|
+
details = page.locator(f"#{identifier}")
|
|
846
|
+
child = details.locator(":scope > :not(summary)").first
|
|
847
|
+
assert child.bounding_box()["x"] == pytest.approx(details.bounding_box()["x"] + 2 + inset)
|
|
848
|
+
# Details overrides do not change the no-JavaScript padded tab fallback.
|
|
849
|
+
expect(page.locator("#nested-outer .tabbed-block")).to_have_css("padding-left", "20px")
|
|
850
|
+
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
|
|
851
|
+
finally:
|
|
852
|
+
context.close()
|
|
853
|
+
|
|
854
|
+
|
|
654
855
|
def test_trademark_glyph_uses_theme_colors(page, site_url: str) -> None:
|
|
655
856
|
page.goto(site_url)
|
|
656
857
|
badge = page.locator(".brand-trademark")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/css/analytics.css
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/heading-link.svg
RENAMED
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/page-edit.svg
RENAMED
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/page-source.svg
RENAMED
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/repository.svg
RENAMED
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/icons/search.svg
RENAMED
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/src/mkdocs_pixel_lab/assets/js/analytics.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/assets/alignment-wide.svg
RENAMED
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/assets/pixel-lab-demo.mp4
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs_pixel_lab-0.2.1 → mkdocs_pixel_lab-0.2.2}/tests/fixture_site/docs/guide/alignment.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|