feat: Refresh docs theme styling and icon set#425
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds Tabler icon support and a ThemeIcon wrapper with many icon components; large CSS theming and DocSearch/icon-mask updates; dynamic footer year placeholder plus runtime footer component; a floating FeedbackWidget (iframe modal) and ResponsiveEmbed class overrides; minor config and SVG tweaks; Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Widget as FeedbackWidget
participant Embed as ResponsiveEmbed (iframe)
participant Survey as External Survey
User->>Widget: Click feedback button
Widget->>Widget: setOpen(true) → render backdrop + dialog
Widget->>Embed: render iframe src=".../survey"
Embed->>Survey: Load survey URL
User->>Embed: Interact with survey
User->>Widget: Click close or press Escape
Widget->>Widget: setOpen(false), restore focus & body overflow, remove listeners
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
unraid-docs | a0c8dc3 | Commit Preview URL Branch Preview URL |
Mar 21 2026, 05:13 PM |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/css/custom.css (1)
385-387:⚠️ Potential issue | 🟡 MinorInvalid CSS:
openis not a CSS property.The
openattribute on<details>elements is an HTML attribute, not a CSS property. This rule will have no effect. To auto-expand targeted details elements, you would need JavaScript.🗑️ Suggested removal
-/* Auto-expand details when targeted */ -details:target { - open: true; -}If auto-expansion is needed, consider using the
:targetselector with JavaScript or a Docusaurus plugin/component that handles this behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/css/custom.css` around lines 385 - 387, The CSS rule using the selector details:target with the property open is invalid because "open" is an HTML attribute, not a CSS property; remove the rule (the selector details:target { open: true; }) from the stylesheet, and if you need auto-expansion of targeted <details> elements implement a small script that detects the :target element (or location.hash) and sets the element.open = true programmatically (or use a Docusaurus plugin/component) — update any references to the details:target selector in the repo accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/css/custom.css`:
- Around line 167-181: The CSS uses the keyword with incorrect casing in the
rule for .DocSearch-Button-Container::before, .DocSearch-MagnifierLabel::before,
and .DocSearch-Close::before; update the background-color property from
"currentColor" to the lowercase "currentcolor" to satisfy Stylelint's CSS
keyword convention and re-run linting to confirm the warning is resolved.
- Around line 358-369: The rule for the external-link pseudo-element selector
a[href^="http"]:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"])::after
uses background-color: currentColor; which triggers the Stylelint casing
rule—change the value to lowercase (background-color: currentcolor;) so the
token matches the linter expectation; update the same occurrence in that
selector and run lint to confirm the fix.
In `@src/theme/Layout/IframeNavigation.tsx`:
- Around line 106-108: The SVG arrow in IframeNavigation.tsx is an open path and
needs stroke styling to render; update the <path> inside the SVG used by the
IframeNavigation component to include stroke attributes (e.g.,
stroke="currentColor", stroke-width="2", stroke-linecap="round",
stroke-linejoin="round") or add equivalent CSS targeting that path so the arrow
becomes visible while preserving currentColor for theming.
---
Outside diff comments:
In `@src/css/custom.css`:
- Around line 385-387: The CSS rule using the selector details:target with the
property open is invalid because "open" is an HTML attribute, not a CSS
property; remove the rule (the selector details:target { open: true; }) from the
stylesheet, and if you need auto-expansion of targeted <details> elements
implement a small script that detects the :target element (or location.hash) and
sets the element.open = true programmatically (or use a Docusaurus
plugin/component) — update any references to the details:target selector in the
repo accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: cdf448d9-9435-4ab5-b389-5867214bad05
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (30)
.gitignoredocusaurus.config.tsi18n/de/docusaurus-theme-classic/footer.jsoni18n/en/docusaurus-theme-classic/footer.jsoni18n/es/docusaurus-theme-classic/footer.jsoni18n/fr/docusaurus-theme-classic/footer.jsoni18n/zh/docusaurus-theme-classic/footer.jsonpackage.jsonsrc/css/custom.csssrc/theme/Admonition/Icon/Danger.tsxsrc/theme/Admonition/Icon/Info.tsxsrc/theme/Admonition/Icon/Note.tsxsrc/theme/Admonition/Icon/Tip.tsxsrc/theme/Admonition/Icon/Warning.tsxsrc/theme/Footer/Copyright/index.tsxsrc/theme/Icon/Arrow/index.tsxsrc/theme/Icon/Close/index.tsxsrc/theme/Icon/Copy/index.tsxsrc/theme/Icon/DarkMode/index.tsxsrc/theme/Icon/Edit/index.tsxsrc/theme/Icon/ExternalLink/index.tsxsrc/theme/Icon/Home/index.tsxsrc/theme/Icon/Language/index.tsxsrc/theme/Icon/LightMode/index.tsxsrc/theme/Icon/Menu/index.tsxsrc/theme/Icon/Success/index.tsxsrc/theme/Icon/SystemColorMode/index.tsxsrc/theme/Icon/WordWrap/index.tsxsrc/theme/Icon/shared.tsxsrc/theme/Layout/IframeNavigation.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/css/custom.css (2)
48-80: Thehtml[data-theme='dark']:rootselector is unconventional but valid.Since
:rootis equivalent tohtmlin HTML documents, this selector is functionally the same ashtml[data-theme='dark']. If the intent is to increase specificity or explicitly scope variables at the root level, consider adding a brief comment explaining the choice for future maintainers.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/css/custom.css` around lines 48 - 80, The selector "html[data-theme='dark']:root" is redundant because :root equals html; either simplify the CSS variable block to use "html[data-theme='dark']" or keep the current selector but add a short inline comment above "html[data-theme='dark']:root" explaining the deliberate use (e.g., to increase specificity or explicitly scope root variables) so future maintainers understand the intent.
359-360: Consider adopting complex:not()notation for broader Stylelint compliance.Stylelint's
selector-not-notationrule prefers complex notation with comma-separated selectors:.theme-doc-markdown a[href^="http"]:not([href*="docs.unraid.net"], [href*="releases.unraid.net"], [href*="localhost"], [href*="127.0.0.1"])::afterThis syntax has solid browser support (Chrome 88+, Firefox 84+, Safari 9+) but does not work in Internet Explorer. If IE support is required, you may need to disable this Stylelint rule or continue using the chained
:not()approach.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/css/custom.css` around lines 359 - 360, The combined external-link selectors (.theme-doc-markdown a[href^="http"]::after and .theme-blog-markdown a[href^="http"]::after) currently use multiple chained :not() pseudo-classes; update them to use a single complex :not() with comma-separated attribute selectors (e.g., :not([href*="docs.unraid.net"], [href*="releases.unraid.net"], [href*="localhost"], [href*="127.0.0.1"])) to satisfy Stylelint's selector-not-notation rule, or if Internet Explorer support is required, keep the chained :not() and instead disable or override that Stylelint rule for this file. Ensure you update both the .theme-doc-markdown and .theme-blog-markdown selectors mentioned in the diff.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/css/custom.css`:
- Around line 48-80: The selector "html[data-theme='dark']:root" is redundant
because :root equals html; either simplify the CSS variable block to use
"html[data-theme='dark']" or keep the current selector but add a short inline
comment above "html[data-theme='dark']:root" explaining the deliberate use
(e.g., to increase specificity or explicitly scope root variables) so future
maintainers understand the intent.
- Around line 359-360: The combined external-link selectors (.theme-doc-markdown
a[href^="http"]::after and .theme-blog-markdown a[href^="http"]::after)
currently use multiple chained :not() pseudo-classes; update them to use a
single complex :not() with comma-separated attribute selectors (e.g.,
:not([href*="docs.unraid.net"], [href*="releases.unraid.net"],
[href*="localhost"], [href*="127.0.0.1"])) to satisfy Stylelint's
selector-not-notation rule, or if Internet Explorer support is required, keep
the chained :not() and instead disable or override that Stylelint rule for this
file. Ensure you update both the .theme-doc-markdown and .theme-blog-markdown
selectors mentioned in the diff.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
src/css/custom.css (2)
167-175:⚠️ Potential issue | 🟡 MinorFix
currentColorkeyword casing in two places.
background-color: currentColor;at Line 174 and Line 368 still violates the configured Stylelint keyword-case rule.🔧 Proposed fix
.DocSearch-Button-Container::before, .DocSearch-MagnifierLabel::before, .DocSearch-Close::before { @@ - background-color: currentColor; + background-color: currentcolor; @@ .theme-doc-markdown a[href^="http"]:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"])::after, .theme-blog-markdown a[href^="http"]:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"])::after { @@ - background-color: currentColor; + background-color: currentcolor;#!/bin/bash # Verify no remaining keyword-case violations for currentColor in this file rg -n 'currentColor' src/css/custom.cssAlso applies to: 366-369
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/css/custom.css` around lines 167 - 175, The CSS uses the mixed-case keyword "currentColor" which violates the Stylelint keyword-case rule; update occurrences in the selectors (e.g. .DocSearch-Button-Container::before, .DocSearch-MagnifierLabel::before, .DocSearch-Close::before and the other block around lines noted) by replacing "currentColor" with the lowercase "currentcolor" (search for the string "currentColor" in src/css/custom.css and replace both instances), then run the provided ripgrep check to verify no remaining occurrences.
359-360:⚠️ Potential issue | 🟡 MinorRefactor chained
:not()selectors to list notation for Stylelint compliance.The chained
:not(...)sequence on Line 359-Line 360 and Line 373-Line 374 triggersselector-not-notation; merge into one:not(selector-list)form.🔧 Proposed fix
-.theme-doc-markdown a[href^="http"]:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"])::after, -.theme-blog-markdown a[href^="http"]:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"])::after { +.theme-doc-markdown a[href^="http"]:not([href*="docs.unraid.net"], [href*="releases.unraid.net"], [href*="localhost"], [href*="127.0.0.1"])::after, +.theme-blog-markdown a[href^="http"]:not([href*="docs.unraid.net"], [href*="releases.unraid.net"], [href*="localhost"], [href*="127.0.0.1"])::after { @@ -.theme-doc-markdown a[href^="http"]:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"]):hover::after, -.theme-blog-markdown a[href^="http"]:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"]):hover::after { +.theme-doc-markdown a[href^="http"]:not([href*="docs.unraid.net"], [href*="releases.unraid.net"], [href*="localhost"], [href*="127.0.0.1"]):hover::after, +.theme-blog-markdown a[href^="http"]:not([href*="docs.unraid.net"], [href*="releases.unraid.net"], [href*="localhost"], [href*="127.0.0.1"]):hover::after {#!/bin/bash # Inspect external-link selectors for chained :not(...) usage rg -n 'theme-(doc|blog)-markdown a\[href\^="http"\].*:not\([^)]*\):not\(' src/css/custom.cssAlso applies to: 373-374
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/css/custom.css` around lines 359 - 360, Replace the chained :not(...) pseudo-classes on the external-link selectors (the rules starting with .theme-doc-markdown a[href^="http"] and .theme-blog-markdown a[href^="http"]) with a single :not(...) using a comma-separated selector list; update both occurrences (the rule blocks that currently include multiple :not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"])) to use one :not([href*="docs.unraid.net"], [href*="releases.unraid.net"], [href*="localhost"], [href*="127.0.0.1"]) so the selectors comply with Stylelint's selector-not-notation rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/css/custom.css`:
- Around line 167-175: The CSS uses the mixed-case keyword "currentColor" which
violates the Stylelint keyword-case rule; update occurrences in the selectors
(e.g. .DocSearch-Button-Container::before, .DocSearch-MagnifierLabel::before,
.DocSearch-Close::before and the other block around lines noted) by replacing
"currentColor" with the lowercase "currentcolor" (search for the string
"currentColor" in src/css/custom.css and replace both instances), then run the
provided ripgrep check to verify no remaining occurrences.
- Around line 359-360: Replace the chained :not(...) pseudo-classes on the
external-link selectors (the rules starting with .theme-doc-markdown
a[href^="http"] and .theme-blog-markdown a[href^="http"]) with a single
:not(...) using a comma-separated selector list; update both occurrences (the
rule blocks that currently include multiple
:not([href*="docs.unraid.net"]):not([href*="releases.unraid.net"]):not([href*="localhost"]):not([href*="127.0.0.1"]))
to use one :not([href*="docs.unraid.net"], [href*="releases.unraid.net"],
[href*="localhost"], [href*="127.0.0.1"]) so the selectors comply with
Stylelint's selector-not-notation rule.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b083314d-84b2-41ad-8677-a535620c1aca
⛔ Files ignored due to path filters (4)
static/img/icons/tabler-chevron-up.svgis excluded by!**/*.svgstatic/img/icons/tabler-external-link.svgis excluded by!**/*.svgstatic/img/icons/tabler-search.svgis excluded by!**/*.svgstatic/img/icons/tabler-x.svgis excluded by!**/*.svg
📒 Files selected for processing (1)
src/css/custom.css
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
src/css/custom.css (1)
15-24: Quote font names to follow CSS best practices.The unquoted font identifiers (
Roboto,Helvetica,Arial,BlinkMacSystemFont) should be quoted to improve consistency and ensure proper handling in edge cases.🧹 Minimal fix
--unraid-brand-font-family: - "nudista-web", -apple-system, system-ui, "Segoe UI", Roboto, Helvetica, - Arial, sans-serif; + "nudista-web", -apple-system, system-ui, "Segoe UI", "Roboto", + "Helvetica", "Arial", sans-serif; @@ --ifm-font-family-base: "Atkinson Hyperlegible Next Variable", system-ui, -apple-system, - BlinkMacSystemFont, "Segoe UI", sans-serif; + "BlinkMacSystemFont", "Segoe UI", sans-serif;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/css/custom.css` around lines 15 - 24, The CSS custom properties --unraid-brand-font-family and --ifm-font-family-base contain unquoted font identifiers; update these variables to quote the font family names mentioned (e.g., "Roboto", "Helvetica", "Arial", "BlinkMacSystemFont") so all font tokens are consistently quoted, preserving the existing comma-separated order and fallback list in each property.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/theme/Layout/FeedbackWidget.tsx`:
- Around line 10-11: The first-paint flash happens because useIframe()
initializes to false then flips, so change useIframe to initialize its state as
undefined (or null) and set a boolean only inside the effect; then update
FeedbackWidget to gate rendering on the iframe check being settled by only
showing the widget when isInIframeState === false (i.e., explicitly false),
keeping the useState(false) for isOpen but ensuring the component returns
null/no markup while isInIframeState is undefined; reference useIframe() and the
isInIframeState variable in FeedbackWidget and the effect/state in
src/hooks/useIframe.ts to implement the change.
- Around line 47-48: The hard-coded English strings in the FeedbackWidget
component need to be routed through Docusaurus i18n helpers; import and use the
Translate component or translate() helper from '@docusaurus/Translate' in
FeedbackWidget and replace literal strings used in attributes and JSX (e.g.,
aria-label="Open feedback panel", title="Share feedback", the panel heading(s)
and button/placeholder texts around lines noted) with translated equivalents so
they render through the site i18n pipeline; update each literal (aria-label,
title, headings, button text, placeholders referenced in FeedbackWidget) to use
Translate or translate({message: ...}) so localization works.
- Around line 13-36: The FeedbackWidget useEffect currently only hides body
scroll and listens for Escape; add focus management and opener trapping: when
opening (isOpen true) save document.activeElement (the opener button), set the
opener button to aria-hidden="true" and tabIndex={-1}, move focus into the modal
by focusing the first focusable element inside the dialog, and install keyboard
handlers to trap Tab/Shift+Tab cycling within the modal; on close restore the
opener button attributes, return focus to the saved element, and remove the
added handlers and revert document.body.style.overflow. Update the effect's
cleanup and the component's opener button props (the element that calls
setIsOpen) to support aria-hidden/tabIndex changes and ensure the modal DOM node
is referenced (e.g., via a ref used in the effect) so you can find first/last
focusable elements for the trap.
---
Nitpick comments:
In `@src/css/custom.css`:
- Around line 15-24: The CSS custom properties --unraid-brand-font-family and
--ifm-font-family-base contain unquoted font identifiers; update these variables
to quote the font family names mentioned (e.g., "Roboto", "Helvetica", "Arial",
"BlinkMacSystemFont") so all font tokens are consistently quoted, preserving the
existing comma-separated order and fallback list in each property.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 650f4a3b-6dc1-465a-b7cb-282281ed5b3f
📒 Files selected for processing (6)
AGENTS.mdsrc/components/ResponsiveEmbed/index.tsxsrc/css/custom.csssrc/theme/Layout/FeedbackWidget.tsxsrc/theme/Layout/IframeNavigation.tsxsrc/theme/Layout/Provider/index.tsx
✅ Files skipped from review due to trivial changes (2)
- AGENTS.md
- src/theme/Layout/IframeNavigation.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/theme/Layout/FeedbackWidget.tsx`:
- Around line 9-16: The focusable selector constant FOCUSABLE_SELECTOR (and the
other identical selector occurrences used for the modal focus trap) currently
omits iframe elements; update the selector(s) to include iframe (e.g., 'iframe'
or 'iframe[src]') so the embedded survey iframe is part of the focusable set and
keyboard navigation can reach it; modify the FOCUSABLE_SELECTOR definition and
any duplicate selectors referenced around the modal/focus-trap logic (the same
selectors at the other occurrences noted) to include the iframe selector.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 6d6f3f08-b2f1-499f-903e-06de294c6742
📒 Files selected for processing (3)
src/css/custom.csssrc/hooks/useIframe.tssrc/theme/Layout/FeedbackWidget.tsx
✅ Files skipped from review due to trivial changes (1)
- src/css/custom.css
Summary
.gstack/directoryTesting
pnpm run test:runpnpm run lintwarn/in translated pages and one pre-existing broken anchor under SMART reportsSummary by CodeRabbit
New Features
Style
Chores
Documentation