mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-29 15:19:00 +03:00
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:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user