-
Notifications
You must be signed in to change notification settings - Fork 1.4k
docs: S2 docs layout + general improvements #9159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 11 commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
2c7e674
close SearchMenu on client navigation
reidbarber 5cb61c3
add footer
reidbarber 33f0724
made Nav and ToC widths static
reidbarber 35069c4
fix min-height issue on mobile
reidbarber 5e84727
show Toast if route can't load
reidbarber 9122573
add toast for clipboard copy failures
reidbarber 45ec5f7
fix React insertion effect
reidbarber 81f27fb
improve markdown menu
reidbarber c35adb7
add skeleton loading for client routing
reidbarber c7b2c20
copy update
reidbarber 217f3df
Merge remote-tracking branch 'origin/main' into s2-docs-general-impro…
reidbarber df6fe71
remote extra startTransitions and use use hook
reidbarber 2bbe51f
improve skeleton loading and optimistic render link selection + ToC
reidbarber 93dca54
add delay to showing skeleton
reidbarber 9338497
fix getPageInfo logic
reidbarber dc3309a
try fixing getPageInfo again
reidbarber 25297d3
try fixing normalizePathname on build
reidbarber aa6ba15
add prefetch onPressStart
reidbarber 9cd4e02
revert optimistic UI and show error toast if fetch fails
reidbarber fbd63dd
fix skeleton title
reidbarber 31683a3
don't clear targetPathname until new navigation
reidbarber 4970161
move prefetch to a global pointerover listener
reidbarber cf27fd3
close search menu when navigation starts
reidbarber 8d77e46
show skeleton loading immediately when navigation starts
reidbarber de49692
Merge remote-tracking branch 'origin/main' into s2-docs-general-impro…
reidbarber d971a15
re-use tag group in SearchMenu and MobileSearchMenu
reidbarber 7d2fb80
fix and extract out search logic
reidbarber 5cfdd17
remove blog and releases index pages from search
reidbarber 6c98a92
reduce size of icons in dnd blog post example
reidbarber 537d8b1
fix Forms password example
reidbarber 751fc05
centralize search logic
reidbarber 77dd142
add escapeKeyBehavior="none" to tag groups
reidbarber 0a7dcbc
fix toc scroll mask
reidbarber f4fd084
simplify pathname logic
reidbarber 67a3b66
remove promises from prefetch cache once resolved
reidbarber aef8e3b
use useOptimistic
reidbarber f3b9f25
use fetchRSC promise as loading source
reidbarber 839f0d3
avoid navigation race conditions
reidbarber 80431b0
prefetch on focus (same as pointerover)
reidbarber 512a045
function for checking if client link
reidbarber 90abcd8
fix search results sorting for All tag
reidbarber b70d7d8
add message to currentAbortController.abort
reidbarber d01efc1
lint
reidbarber ff3c90c
Merge remote-tracking branch 'origin/main' into s2-docs-general-impro…
reidbarber File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,61 +1,76 @@ | ||
| 'use client'; | ||
|
|
||
| import {ActionButton, Menu, MenuItem, MenuTrigger, Text} from '@react-spectrum/s2'; | ||
| import {ActionButton, Menu, MenuItem, MenuTrigger, Text, UNSTABLE_ToastQueue as ToastQueue} from '@react-spectrum/s2'; | ||
| import CheckmarkCircle from '@react-spectrum/s2/icons/CheckmarkCircle'; | ||
| import Copy from '@react-spectrum/s2/icons/Copy'; | ||
| import OpenIn from '@react-spectrum/s2/icons/OpenIn'; | ||
| import React, {useCallback} from 'react'; | ||
| import {getLibraryFromUrl, getLibraryLabel} from './library'; | ||
| import More from '@react-spectrum/s2/icons/More'; | ||
| import React, {useCallback, useEffect, useRef, useState} from 'react'; | ||
| import {style} from '@react-spectrum/s2/style' with {type: 'macro'}; | ||
|
|
||
| interface MarkdownMenuProps { | ||
| url: string | undefined | ||
| } | ||
|
|
||
| export function MarkdownMenu({url}: MarkdownMenuProps) { | ||
| let mdUrl = (url ?? '').replace(/\.html?$/i, '') + '.md'; | ||
| let [isCopied, setIsCopied] = useState(false); | ||
| let timeout = useRef<ReturnType<typeof setTimeout> | null>(null); | ||
|
|
||
| let pageUrl = typeof window !== 'undefined' && url ? new URL(url, window.location.origin).href : url ?? ''; | ||
| let fullMdUrl = typeof window !== 'undefined' && mdUrl ? new URL(mdUrl, window.location.origin).href : mdUrl; | ||
| let library = url ? getLibraryLabel(getLibraryFromUrl(url)) : ''; | ||
| let aiPrompt = `Answer questions about the following ${library} documentation page: ${pageUrl}\nMarkdown source: ${fullMdUrl}`; | ||
| let chatGptUrl = `https://chatgpt.com/?q=${encodeURIComponent(aiPrompt)}`; | ||
| let claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(aiPrompt)}`; | ||
|
|
||
| let onAction = useCallback(async (key: import('react-aria-components').Key) => { | ||
| let action = String(key); | ||
| switch (action) { | ||
| case 'copy': { | ||
| if (typeof navigator !== 'undefined' && navigator.clipboard) { | ||
| try { | ||
| let response = await fetch(mdUrl); | ||
| // Fallback to copying the URL if the request fails or isn't ok. | ||
| if (!response.ok) { | ||
| throw new Error('Failed to fetch markdown'); | ||
| } | ||
|
|
||
| let markdown = await response.text(); | ||
| await navigator.clipboard.writeText(markdown); | ||
| } catch { | ||
| // ignore failures (e.g., insecure context, network errors) | ||
| } | ||
| } | ||
| break; | ||
| useEffect(() => { | ||
| return () => { | ||
| if (timeout.current) { | ||
| clearTimeout(timeout.current); | ||
| } | ||
| case 'view': { | ||
| if (typeof window !== 'undefined') { | ||
| window.open(mdUrl, '_blank'); | ||
| } | ||
| break; | ||
| }; | ||
| }, []); | ||
|
|
||
| let handleCopy = useCallback(async () => { | ||
| if (timeout.current) { | ||
| clearTimeout(timeout.current); | ||
| } | ||
| if (typeof navigator !== 'undefined' && navigator.clipboard) { | ||
| try { | ||
| let response = await fetch(mdUrl); | ||
| let markdown = await response.text(); | ||
| await navigator.clipboard.writeText(markdown); | ||
| setIsCopied(true); | ||
| timeout.current = setTimeout(() => setIsCopied(false), 2000); | ||
| } catch { | ||
| ToastQueue.negative('Failed to copy markdown.'); | ||
| } | ||
| } | ||
| }, [mdUrl]); | ||
|
|
||
| return ( | ||
| <MenuTrigger> | ||
| <ActionButton size="L" isQuiet aria-label="Markdown options"> | ||
| <Copy /> | ||
| <div className={style({display: 'flex', justifyContent: 'space-between', paddingX: 4, paddingBottom: 16})}> | ||
| <ActionButton isQuiet size="M" onPress={handleCopy}> | ||
| {isCopied ? <CheckmarkCircle /> : <Copy />} | ||
| <Text>Copy for LLM</Text> | ||
| </ActionButton> | ||
| <Menu onAction={onAction}> | ||
| <MenuItem id="copy"> | ||
| <Copy /> | ||
| <Text>Copy Page as Markdown</Text> | ||
| </MenuItem> | ||
| <MenuItem id="view"> | ||
| <OpenIn /> | ||
| <Text>View Page as Markdown</Text> | ||
| </MenuItem> | ||
| </Menu> | ||
| </MenuTrigger> | ||
| <MenuTrigger> | ||
| <ActionButton size="M" isQuiet aria-label="Markdown options"> | ||
| <More /> | ||
| </ActionButton> | ||
| <Menu> | ||
| <MenuItem id="view" href={mdUrl} target="_blank"> | ||
| View as Markdown | ||
| </MenuItem> | ||
| <MenuItem id="chatgpt" href={chatGptUrl} target="_blank"> | ||
| Open in ChatGPT | ||
| </MenuItem> | ||
| <MenuItem id="claude" href={claudeUrl} target="_blank"> | ||
| Open in Claude | ||
| </MenuItem> | ||
| </Menu> | ||
| </MenuTrigger> | ||
| </div> | ||
| ); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question for the team: do we prefer this at the bottom of the page or at the top (i.e. above "on this page")? Most sites seem to have it at the top. I don't mind the bottom but it's a little less prominent. Also moves around a bit depending on the length of the toc.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My reasoning was that the table of contents is more useful most of the time, so it's better when scanning to read that first. Also if we end up adding more actions (feedback button, etc.) it might crowd the top. Definitely open to changing this though.
Also for pages with many sections it renders at the bottom and the ToC has scrolling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO I like it at the bottom, but it really depends on how prominent we want to make it