Miscellaneous fixes (#23661)

* update face recognition docs

* clarify

* improve faq grouping

* add faqitem component

* add enable http link for reolinks

* update plus docs

* update autotracking faq

* fix typos
This commit is contained in:
Josh Hawkins
2026-07-10 07:09:15 -06:00
committed by GitHub
parent 20c2be4368
commit f6596ac7b0
22 changed files with 437 additions and 75 deletions
+66
View File
@@ -0,0 +1,66 @@
import React, { useState, useEffect } from "react";
import Heading from "@theme/Heading";
import styles from "./styles.module.css";
// A single FAQ entry.
//
// The question is a real anchored heading (via @theme/Heading), so on desktop
// it gets the standard hover "#" hash link and the answer is always shown. On
// mobile the heading text is a button that toggles its answer, keeping long
// FAQ pages short. The desktop/mobile split is pure CSS (Docusaurus breakpoint:
// 996px), so there is no hydration flash. The answer is always rendered into
// the DOM, so search engines and the docs AI bot can read it regardless of
// layout or collapsed state. The heading id resolves deep links on both layouts
// and auto-expands the entry on mobile when it is the link target.
export default function FaqItem({ id, question, children }) {
const [open, setOpen] = useState(false);
useEffect(() => {
const openIfTargeted = () => {
if (window.location.hash === `#${id}`) {
setOpen(true);
}
};
openIfTargeted();
window.addEventListener("hashchange", openIfTargeted);
return () => window.removeEventListener("hashchange", openIfTargeted);
}, [id]);
const toggle = () => {
const next = !open;
setOpen(next);
// Reflect the entry in the URL like clicking the heading anchor, so an
// opened answer is shareable. Use replaceState to avoid history spam and
// an abrupt scroll. Clear it on close if it currently points here.
if (next) {
if (window.location.hash !== `#${id}`) {
window.history.replaceState(null, "", `#${id}`);
}
} else if (window.location.hash === `#${id}`) {
window.history.replaceState(
null,
"",
window.location.pathname + window.location.search,
);
}
};
return (
<div className={styles.item} data-open={open || undefined}>
<Heading as="h4" id={id} className={styles.heading}>
<button
type="button"
className={styles.toggle}
aria-expanded={open}
aria-controls={`${id}-content`}
onClick={toggle}
>
{question}
</button>
</Heading>
<div id={`${id}-content`} className={styles.content}>
{children}
</div>
</div>
);
}
@@ -0,0 +1,87 @@
/*
* FAQ entry: collapsible on mobile, static heading + expanded answer on
* desktop. The split is pure CSS (Docusaurus breakpoint: 996px) so there is
* no hydration flash. The answer is always rendered into the DOM, so search
* engines and the docs AI bot can read it regardless of layout or state.
*/
.item {
scroll-margin-top: calc(var(--ifm-navbar-height) + 1rem);
}
.heading {
margin: 0;
}
/* Mobile: the heading text is a full-width clickable toggle row. */
.toggle {
display: flex;
align-items: center;
gap: 0.6rem;
width: 100%;
padding: 0.85rem 0;
border: none;
border-bottom: 1px solid var(--ifm-color-emphasis-200);
background: none;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
}
.toggle::before {
content: "";
flex: 0 0 auto;
width: 0.5rem;
height: 0.5rem;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(-45deg);
transition: transform var(--ifm-transition-fast, 200ms) ease;
}
.item[data-open] .toggle::before {
transform: rotate(45deg);
}
.content {
display: none;
padding: 0 0 0.85rem;
}
.item[data-open] .content {
display: block;
}
/* Hide the hover hash link on mobile (no hover; avoids a stray empty line). */
.heading :global(.hash-link) {
display: none;
}
/* Desktop: render as a normal expanded heading + answer. */
@media (min-width: 997px) {
.heading {
margin: 1.75rem 0 0.5rem;
}
.toggle {
display: inline;
width: auto;
padding: 0;
border: none;
cursor: default;
}
.toggle::before {
display: none;
}
.content {
display: block;
padding: 0;
}
.heading :global(.hash-link) {
display: inline;
}
}