Skip to content

Conversation

@dongguacute
Copy link
Collaborator

@dongguacute dongguacute commented Dec 18, 2025

  • feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:

  • Share state management with reactive store
  • Popup component with content preview and image download
  • Automatic injection of share buttons to section headers
  • QR code generation for sharing links
  • New dependencies for QR code and DOM capture

feat(share): implement share functionality with popup and section but…

  • feat(share): improve share functionality and UI
  • Add route path check to limit share button injection to docs pages
  • Make share button always visible and remove hover scale effect
  • Add click feedback with green text color on share button
  • Update share popup with better filename, body overflow handling, and style tweaks
  • Change button title from "分享此页" to "保存图片"
  • feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:

  • Share state management with reactive store
  • Popup component with content preview and image download
  • Automatic injection of share buttons to section headers
  • QR code generation for sharing links
  • New dependencies for QR code and DOM capture
  • feat(share): improve share functionality and UI
  • Add route path check to limit share button injection to docs pages
  • Make share button always visible and remove hover scale effect
  • Add click feedback with green text color on share button
  • Update share popup with better filename, body overflow handling, and style tweaks
  • Change button title from "分享此页" to "保存图片"
  • refactor(share): improve share button injection and styling
  • Change share button container positioning to appear at section end
  • Replace element class check with more reliable processed marker
  • Adjust popup backdrop styling for better visibility
  • Move container styles from inline to CSS class
  • feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:

  • Share state management with reactive store
  • Popup component with content preview and image download
  • Automatic injection of share buttons to section headers
  • QR code generation for sharing links
  • New dependencies for QR code and DOM capture
  • feat(share): improve share functionality and UI
  • Add route path check to limit share button injection to docs pages
  • Make share button always visible and remove hover scale effect
  • Add click feedback with green text color on share button
  • Update share popup with better filename, body overflow handling, and style tweaks
  • Change button title from "分享此页" to "保存图片"
  • refactor(share): improve share button injection and styling
  • Change share button container positioning to appear at section end
  • Replace element class check with more reliable processed marker
  • Adjust popup backdrop styling for better visibility
  • Move container styles from inline to CSS class
  • feat(share-button): improve styling and positioning of share button
  • Change button position to be aligned with heading
  • Update button styling to match theme colors
  • Simplify DOM insertion logic by removing section traversal
  • Add hover effects and consistent sizing
  • style: update share button background color for better visibility

  • feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:

  • Share state management with reactive store
  • Popup component with content preview and image download
  • Automatic injection of share buttons to section headers
  • QR code generation for sharing links
  • New dependencies for QR code and DOM capture

feat(share): implement share functionality with popup and section but…

  • feat(share): improve share functionality and UI
  • Add route path check to limit share button injection to docs pages
  • Make share button always visible and remove hover scale effect
  • Add click feedback with green text color on share button
  • Update share popup with better filename, body overflow handling, and style tweaks
  • Change button title from "分享此页" to "保存图片"
  • refactor(share): improve share button injection and styling
  • Change share button container positioning to appear at section end
  • Replace element class check with more reliable processed marker
  • Adjust popup backdrop styling for better visibility
  • Move container styles from inline to CSS class
  • feat(share-button): improve styling and positioning of share button
  • Change button position to be aligned with heading
  • Update button styling to match theme colors
  • Simplify DOM insertion logic by removing section traversal
  • Add hover effects and consistent sizing
  • style: update share button background color for better visibility

* feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:
- Share state management with reactive store
- Popup component with content preview and image download
- Automatic injection of share buttons to section headers
- QR code generation for sharing links
- New dependencies for QR code and DOM capture

* Merge pull request #49 from dongguacute/main

feat(share): implement share functionality with popup and section but…

* feat(share): improve share functionality and UI

- Add route path check to limit share button injection to docs pages
- Make share button always visible and remove hover scale effect
- Add click feedback with green text color on share button
- Update share popup with better filename, body overflow handling, and style tweaks
- Change button title from "分享此页" to "保存图片"

* fix (#51)

* feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:
- Share state management with reactive store
- Popup component with content preview and image download
- Automatic injection of share buttons to section headers
- QR code generation for sharing links
- New dependencies for QR code and DOM capture

* feat(share): improve share functionality and UI

- Add route path check to limit share button injection to docs pages
- Make share button always visible and remove hover scale effect
- Add click feedback with green text color on share button
- Update share popup with better filename, body overflow handling, and style tweaks
- Change button title from "分享此页" to "保存图片"

---------

Signed-off-by: Cherry🍒 <132185099+dongguacute@users.noreply.github.com>

* refactor(share): improve share button injection and styling

- Change share button container positioning to appear at section end
- Replace element class check with more reliable processed marker
- Adjust popup backdrop styling for better visibility
- Move container styles from inline to CSS class

* fix (#52)

* feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:
- Share state management with reactive store
- Popup component with content preview and image download
- Automatic injection of share buttons to section headers
- QR code generation for sharing links
- New dependencies for QR code and DOM capture

* feat(share): improve share functionality and UI

- Add route path check to limit share button injection to docs pages
- Make share button always visible and remove hover scale effect
- Add click feedback with green text color on share button
- Update share popup with better filename, body overflow handling, and style tweaks
- Change button title from "分享此页" to "保存图片"

* refactor(share): improve share button injection and styling

- Change share button container positioning to appear at section end
- Replace element class check with more reliable processed marker
- Adjust popup backdrop styling for better visibility
- Move container styles from inline to CSS class

---------

Signed-off-by: Cherry🍒 <132185099+dongguacute@users.noreply.github.com>

* feat(share-button): improve styling and positioning of share button

- Change button position to be aligned with heading
- Update button styling to match theme colors
- Simplify DOM insertion logic by removing section traversal
- Add hover effects and consistent sizing

* style: update share button background color for better visibility

* fix (#53)

* feat(share): implement share functionality with popup and section buttons

Add share state management, popup component with QR code generation, and section share buttons. Includes:
- Share state management with reactive store
- Popup component with content preview and image download
- Automatic injection of share buttons to section headers
- QR code generation for sharing links
- New dependencies for QR code and DOM capture

* Merge pull request #49 from dongguacute/main

feat(share): implement share functionality with popup and section but…

* feat(share): improve share functionality and UI

- Add route path check to limit share button injection to docs pages
- Make share button always visible and remove hover scale effect
- Add click feedback with green text color on share button
- Update share popup with better filename, body overflow handling, and style tweaks
- Change button title from "分享此页" to "保存图片"

* refactor(share): improve share button injection and styling

- Change share button container positioning to appear at section end
- Replace element class check with more reliable processed marker
- Adjust popup backdrop styling for better visibility
- Move container styles from inline to CSS class

* feat(share-button): improve styling and positioning of share button

- Change button position to be aligned with heading
- Update button styling to match theme colors
- Simplify DOM insertion logic by removing section traversal
- Add hover effects and consistent sizing

* style: update share button background color for better visibility

---------

Signed-off-by: Cherry🍒 <132185099+dongguacute@users.noreply.github.com>

---------

Signed-off-by: Cherry🍒 <132185099+dongguacute@users.noreply.github.com>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 18, 2025

Deploying ab with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8f0441d
Status: ✅  Deploy successful!
Preview URL: https://7f3a6695.ab-7pz.pages.dev
Branch Preview URL: https://add-sharecard.ab-7pz.pages.dev

View logs

@ChisakaKanako ChisakaKanako marked this pull request as draft December 18, 2025 21:33
epifirumu and others added 5 commits December 19, 2025 08:55
Add ability to display tags in share popup by extending share state interface
Include frontmatter tags and inline badges as share tags
Style tags with appropriate colors based on their type
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive share functionality for VitePress documentation, allowing users to share sections of documentation as images with QR codes. The implementation includes:

  • State management for share operations with reactive store
  • Popup component with content preview and image download capability
  • Automatic injection of share buttons next to H2 headings
  • QR code generation for sharing links
  • Integration with VitePress theme system

Key Changes

  • New dependencies: Added qrcode, @zumer/snapdom for QR code generation and DOM-to-image conversion
  • Component architecture: Created modular component system with SharePopup, ShareButtonInjector, and InjectedShareButton
  • Theme integration: Extended VitePress theme with share functionality in navigation and content areas

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
pnpm-lock.yaml Added new dependencies for QR code generation and DOM capture functionality
package.json Added qrcode, @zumer/snapdom, @types/qrcode, and vue dependencies
docs/.vitepress/theme/style.css Hidden header anchors to clean up share card appearance
docs/.vitepress/theme/index.ts Integrated share components into theme layout
docs/.vitepress/theme/components/shareState.ts Implemented reactive state management for share functionality
docs/.vitepress/theme/components/share.vue Updated existing share component with disabled state logic
docs/.vitepress/theme/components/index.ts Created component registry and export system
docs/.vitepress/theme/components/SharePopup.vue Implemented modal popup with QR code and image download
docs/.vitepress/theme/components/ShareButtonInjector.vue Created DOM mutation observer to inject share buttons dynamically
docs/.vitepress/theme/components/InjectedShareButton.vue Implemented individual share button component
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +29 to +31
function getIsDisabled() {
return !isMounted.value || !shareLink.value || shareSuccess.value
}
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name getIsDisabled is misleading because it sounds like a getter for a property, but it's actually computing a boolean value. The function should be renamed to a more descriptive name that indicates it's computing the disabled state, such as computeDisabledState or isButtonDisabled.

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +117
<Transition name="fade">
<div v-if="shareState.isOpen" class="share-overlay" @click.self="closeShare">
<div class="share-container">
<!-- The Card to Capture -->
<div ref="cardRef" class="share-card">
<!-- Main Content -->
<div class="card-content">
<h2 class="card-title">
{{ shareState.title }}
<div class="card-tags" v-if="shareState.tags && shareState.tags.length">
<span v-for="tag in shareState.tags" :key="tag.text" class="tag" :class="tag.type">{{ tag.text }}</span>
</div>
</h2>
<div class="card-url">{{ shareState.url }}</div>

<div class="card-body vp-doc" v-html="shareState.content"></div>

<div class="card-footer">
<div class="footer-info">
<div class="site-logo">
aboutTrans
</div>
<div class="date">{{ formatDate() }}</div>
</div>
<div class="qr-code" v-if="state.qrCodeUrl">
<img :src="state.qrCodeUrl" alt="QR Code" />
</div>
</div>
</div>
</div>

<!-- Action Buttons -->
<div class="actions">
<button class="action-btn cancel" @click="closeShare">
关闭
</button>

<button class="action-btn download" @click="handleDownload" :disabled="state.isGenerating">
保存
</button>
</div>
</div>
</div>
</Transition>
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing accessibility: The share button in SharePopup.vue should have proper ARIA labels and keyboard navigation support. The overlay should also trap focus within the modal and restore focus when closed. Consider adding aria-modal="true", role="dialog", and implementing focus trap for better accessibility.

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +115
const observeDocContainer = (doc: Element) => {
// Cleanup old doc observer
if (observer) observer.disconnect()
// Initial scan
scanAndInject()
// Watch for changes inside the doc container
observer = new MutationObserver(() => {
scanAndInject()
})
observer.observe(doc, { childList: true, subtree: true })
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scanAndInject function is called on every mutation, which could lead to performance issues on pages with frequent DOM changes. Consider debouncing this function call to reduce unnecessary processing.

Copilot uses AI. Check for mistakes.
Comment on lines +82 to +91
// Mount the Share Button Component
const app = createApp(InjectedShareButton, { onClick: handleShare })
app.mount(btn)
mountedApps.push(app)
container.appendChild(btn)
// Insert container at the end of h2
h2.appendChild(container)
}
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The component creates a new Vue app instance for each share button using createApp and mounts it. This is an anti-pattern and inefficient. Consider using a single component instance or Vue's teleport feature instead of creating multiple app instances, which can lead to memory overhead and slower performance.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +36
watch(() => shareState.isOpen, async (val) => {
if (typeof window !== 'undefined') {
document.body.style.overflow = val ? 'hidden' : ''
}
if (val && shareState.url) {
try {
const QRCode = await import('qrcode')
// Handle both ESM default export and CJS export
const toDataURL = QRCode.toDataURL || (QRCode.default && QRCode.default.toDataURL)
if (toDataURL) {
state.qrCodeUrl = await toDataURL(shareState.url, {
margin: 2,
width: 200,
color: {
dark: '#3c3c43',
light: '#ffffff'
}
})
}
} catch (e) {
console.error(e)
}
}
})
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling for QR code generation. If the dynamic import or toDataURL call fails, the error is only logged to console but the user isn't notified. Consider showing a fallback UI or error message when QR code generation fails.

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +59
const handleDownload = async () => {
if (!cardRef.value || state.isGenerating) return
state.isGenerating = true
try {
// Wait for fonts/images if needed
await nextTick()
// Dynamic import to avoid SSR issues
const { snapdom } = await import('@zumer/snapdom')
// Using snapdom to download
await snapdom.download(cardRef.value, {
filename: `${shareState.title}|aboutTrans`,
scale: 2, // High res
})
} catch (e) {
console.error('Failed to generate image:', e)
} finally {
state.isGenerating = false
}
}
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error message for the user when image download fails. The error is logged to console but users won't know what went wrong. Consider adding a user-visible error notification when the download operation fails.

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +142
// Doc container not ready, watch body for its appearance
bodyObserver = new MutationObserver(() => {
const doc = getDocContainer()
if (doc) {
bodyObserver?.disconnect()
bodyObserver = null
observeDocContainer(doc)
}
})
bodyObserver.observe(document.body, { childList: true, subtree: true })
}
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential memory leak: The MutationObserver is watching for changes with childList: true, subtree: true on the entire document.body when the doc container isn't found. This can lead to performance issues on pages with frequent DOM mutations. Consider adding a timeout or maximum attempt limit to stop observing after a reasonable period, or use a more targeted selector.

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +42
<button class="share-button" :class="[
isClicked ? '!text-green-400' : '',
isMounted ? '' : '!cursor-wait',
]" :disabled="!isMounted" @click.stop.prevent="handleClick()" title="保存图片">
<span flex items-center justify-center>
<svg width="14" height="14" viewBox="0 0 18 18" fill="none" xmlns="www.w3.org/2000/svg">
<path d="M10.5 2.8125H14.625C14.9357 2.8125 15.1875 3.06434 15.1875 3.375V14.625C15.1875 14.9357 14.9357 15.1875 14.625 15.1875H3.375C3.06434 15.1875 2.8125 14.9357 2.8125 14.625V8.5M3.98602 15.1875L11.6958 7.47703C11.748 7.42473 11.8101 7.38324 11.8783 7.35494C11.9466 7.32663 12.0198 7.31206 12.0938 7.31206C12.1677 7.31206 12.2409 7.32663 12.3092 7.35494C12.3774 7.38324 12.4395 7.42473 12.4917 7.47703L15.1875 10.1735M6 2L8 4L6 6M2 2L4 4L2 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</span>
</button>
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing accessibility: The injected share button lacks proper ARIA labels. The button has a title attribute but should also include aria-label for screen readers. Additionally, the button should be keyboard accessible and announce its state changes when clicked.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +31
function getIsDisabled() {
return !isMounted.value || !shareLink.value || shareSuccess.value
}
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The computed function is not actually a computed property but a regular function. Since this function is called in the template directly, consider making it a proper computed property using computed() or simplifying the logic by inlining it in the template. This will improve performance by avoiding unnecessary function calls on each render.

Copilot uses AI. Check for mistakes.
Comment on lines +88 to +91
}

.header-anchor {
opacity: 0 !important;
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The header-anchor opacity is set to !important which might interfere with VitePress's built-in functionality. This could break the default anchor link behavior. Consider using a more specific selector or checking if this is truly necessary, as hiding the anchor links completely may reduce usability.

Suggested change
}
.header-anchor {
opacity: 0 !important;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants