优化互动区样式
This commit is contained in:
@@ -7,3 +7,4 @@ dist/
|
|||||||
!.env.example
|
!.env.example
|
||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
.obsidian/
|
.obsidian/
|
||||||
|
.pnpm-store/
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
---
|
||||||
|
import TwikooComments from '@/components/TwikooComments.astro';
|
||||||
|
import Webmentions from '@/components/Webmentions.astro';
|
||||||
|
import { siteConfig } from '@/site.config';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
commentsEnabled: boolean;
|
||||||
|
path: string;
|
||||||
|
target: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { commentsEnabled, path, target } = Astro.props;
|
||||||
|
const webmentionsEnabled = siteConfig.webmentions.enabled && Boolean(siteConfig.webmentions.endpoint.trim());
|
||||||
|
const commentsConfigured = siteConfig.comments.provider === 'twikoo';
|
||||||
|
const showComments = commentsEnabled && commentsConfigured;
|
||||||
|
---
|
||||||
|
|
||||||
|
{(webmentionsEnabled || showComments) && <section
|
||||||
|
class="engagement-shell"
|
||||||
|
aria-label="文章互动"
|
||||||
|
data-engagement-tabs
|
||||||
|
data-pagefind-ignore="all"
|
||||||
|
>
|
||||||
|
<div class="engagement-tablist" role="tablist" aria-label="文章互动方式">
|
||||||
|
{webmentionsEnabled && <button
|
||||||
|
class="engagement-tab"
|
||||||
|
id="engagement-tab-webmentions"
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
aria-controls="engagement-panel-webmentions"
|
||||||
|
aria-selected="true"
|
||||||
|
data-engagement-tab="webmentions"
|
||||||
|
>WebMention</button>}
|
||||||
|
{showComments && <button
|
||||||
|
class="engagement-tab"
|
||||||
|
id="engagement-tab-comments"
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
aria-controls="engagement-panel-comments"
|
||||||
|
aria-selected={webmentionsEnabled ? 'false' : 'true'}
|
||||||
|
tabindex={webmentionsEnabled ? -1 : 0}
|
||||||
|
data-engagement-tab="comments"
|
||||||
|
>评论</button>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{webmentionsEnabled && <div
|
||||||
|
class="engagement-panel"
|
||||||
|
id="engagement-panel-webmentions"
|
||||||
|
role="tabpanel"
|
||||||
|
aria-labelledby="engagement-tab-webmentions"
|
||||||
|
data-engagement-panel="webmentions"
|
||||||
|
>
|
||||||
|
<Webmentions target={target} />
|
||||||
|
</div>}
|
||||||
|
|
||||||
|
{showComments && <div
|
||||||
|
class="engagement-panel"
|
||||||
|
id="engagement-panel-comments"
|
||||||
|
role="tabpanel"
|
||||||
|
aria-labelledby="engagement-tab-comments"
|
||||||
|
data-engagement-panel="comments"
|
||||||
|
hidden={webmentionsEnabled}
|
||||||
|
>
|
||||||
|
<TwikooComments enabled={commentsEnabled} path={path} />
|
||||||
|
</div>}
|
||||||
|
</section>}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.engagement-shell {
|
||||||
|
width: min(100%, var(--article-content-width));
|
||||||
|
margin: 4.375rem auto 0;
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
color: var(--color-text);
|
||||||
|
font-family: var(--reading-font-family);
|
||||||
|
font-size: .94rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-tablist {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
min-height: 3.25rem;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-tab {
|
||||||
|
position: relative;
|
||||||
|
align-self: stretch;
|
||||||
|
padding: 0 .125rem;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--color-muted);
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: .9375rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-tab::after {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: -1px;
|
||||||
|
left: 0;
|
||||||
|
height: 2px;
|
||||||
|
background: var(--color-accent);
|
||||||
|
content: '';
|
||||||
|
opacity: 0;
|
||||||
|
transform: scaleX(.5);
|
||||||
|
transition: opacity 160ms ease, transform 160ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-tab:is(:hover, [aria-selected='true']) {
|
||||||
|
color: var(--color-accent-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-tab[aria-selected='true']::after {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-tab:focus-visible {
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
outline: 1px solid var(--color-accent);
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-panel {
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-panel[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 37.5rem) {
|
||||||
|
.engagement-shell {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 3.25rem;
|
||||||
|
font-size: .9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-tablist {
|
||||||
|
min-height: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engagement-panel {
|
||||||
|
padding-top: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
type EngagementTabName = 'webmentions' | 'comments';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
__eidolonEngagementTabsBound?: boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabNameFromHash = (): EngagementTabName | null => {
|
||||||
|
if (window.location.hash === '#comments') return 'comments';
|
||||||
|
if (window.location.hash === '#webmentions') return 'webmentions';
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const activateEngagementTab = (
|
||||||
|
root: HTMLElement,
|
||||||
|
name: EngagementTabName,
|
||||||
|
focus = false
|
||||||
|
) => {
|
||||||
|
const tabs = Array.from(root.querySelectorAll<HTMLButtonElement>('[data-engagement-tab]'));
|
||||||
|
const panels = Array.from(root.querySelectorAll<HTMLElement>('[data-engagement-panel]'));
|
||||||
|
const activeTab = tabs.find((tab) => tab.dataset.engagementTab === name);
|
||||||
|
if (!activeTab) return;
|
||||||
|
|
||||||
|
for (const tab of tabs) {
|
||||||
|
const active = tab === activeTab;
|
||||||
|
tab.setAttribute('aria-selected', String(active));
|
||||||
|
tab.tabIndex = active ? 0 : -1;
|
||||||
|
}
|
||||||
|
for (const panel of panels) {
|
||||||
|
panel.hidden = panel.dataset.engagementPanel !== name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (focus) activeTab.focus();
|
||||||
|
root.dispatchEvent(new CustomEvent('engagement:tab-change', {
|
||||||
|
bubbles: true,
|
||||||
|
detail: { tab: name }
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const bindEngagementTabs = () => {
|
||||||
|
const root = document.querySelector<HTMLElement>('[data-engagement-tabs]');
|
||||||
|
if (!root || root.dataset.engagementTabsBound) return;
|
||||||
|
root.dataset.engagementTabsBound = 'true';
|
||||||
|
|
||||||
|
const tabs = Array.from(root.querySelectorAll<HTMLButtonElement>('[data-engagement-tab]'));
|
||||||
|
const initialTab = tabNameFromHash() ?? (tabs[0]?.dataset.engagementTab as EngagementTabName | undefined);
|
||||||
|
if (initialTab) activateEngagementTab(root, initialTab);
|
||||||
|
|
||||||
|
for (const tab of tabs) {
|
||||||
|
tab.addEventListener('click', () => {
|
||||||
|
activateEngagementTab(root, tab.dataset.engagementTab as EngagementTabName);
|
||||||
|
});
|
||||||
|
tab.addEventListener('keydown', (event) => {
|
||||||
|
if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return;
|
||||||
|
event.preventDefault();
|
||||||
|
const currentIndex = tabs.indexOf(tab);
|
||||||
|
const nextIndex = event.key === 'Home'
|
||||||
|
? 0
|
||||||
|
: event.key === 'End'
|
||||||
|
? tabs.length - 1
|
||||||
|
: (currentIndex + (event.key === 'ArrowRight' ? 1 : -1) + tabs.length) % tabs.length;
|
||||||
|
const nextName = tabs[nextIndex]?.dataset.engagementTab as EngagementTabName | undefined;
|
||||||
|
if (nextName) activateEngagementTab(root, nextName, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!window.__eidolonEngagementTabsBound) {
|
||||||
|
window.__eidolonEngagementTabsBound = true;
|
||||||
|
document.addEventListener('astro:page-load', bindEngagementTabs);
|
||||||
|
window.addEventListener('hashchange', () => {
|
||||||
|
const root = document.querySelector<HTMLElement>('[data-engagement-tabs]');
|
||||||
|
const tab = tabNameFromHash();
|
||||||
|
if (root && tab) activateEngagementTab(root, tab);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
bindEngagementTabs();
|
||||||
|
</script>
|
||||||
@@ -39,6 +39,8 @@
|
|||||||
const initCurrentComments = () => {
|
const initCurrentComments = () => {
|
||||||
const root = document.querySelector('#twikoo-comments');
|
const root = document.querySelector('#twikoo-comments');
|
||||||
if (!(root instanceof HTMLElement) || root.dataset.twikooBound) return;
|
if (!(root instanceof HTMLElement) || root.dataset.twikooBound) return;
|
||||||
|
const panel = root.closest('[data-engagement-panel]');
|
||||||
|
if (panel instanceof HTMLElement && panel.hidden) return;
|
||||||
let config;
|
let config;
|
||||||
try {
|
try {
|
||||||
config = JSON.parse(root.dataset.twikooConfig ?? '{}');
|
config = JSON.parse(root.dataset.twikooConfig ?? '{}');
|
||||||
@@ -62,6 +64,7 @@
|
|||||||
|
|
||||||
initCurrentComments();
|
initCurrentComments();
|
||||||
document.addEventListener('astro:page-load', initCurrentComments);
|
document.addEventListener('astro:page-load', initCurrentComments);
|
||||||
|
document.addEventListener('engagement:tab-change', initCurrentComments);
|
||||||
document.addEventListener('astro:before-swap', () => {
|
document.addEventListener('astro:before-swap', () => {
|
||||||
document.querySelector('#twikoo-comments')?.replaceChildren();
|
document.querySelector('#twikoo-comments')?.replaceChildren();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
|
|||||||
} : null;
|
} : null;
|
||||||
---
|
---
|
||||||
{enabled && config && <section class="comments-shell" id="comments" aria-labelledby="comments-title">
|
{enabled && config && <section class="comments-shell" id="comments" aria-labelledby="comments-title">
|
||||||
<h2 id="comments-title">评论</h2>
|
<h2 class="sr-only" id="comments-title">评论</h2>
|
||||||
<div id="twikoo-comments" data-twikoo-config={JSON.stringify(config)} data-twikoo-state="idle"></div>
|
<div id="twikoo-comments" data-twikoo-config={JSON.stringify(config)} data-twikoo-state="idle"></div>
|
||||||
</section>}
|
</section>}
|
||||||
|
|
||||||
{enabled && !config && <section class="comments-shell comments-preview" id="comments" aria-labelledby="comments-title" data-pagefind-ignore="all">
|
{enabled && !config && <section class="comments-shell comments-preview" id="comments" aria-labelledby="comments-title" data-pagefind-ignore="all">
|
||||||
<h2 id="comments-title">评论</h2>
|
<h2 class="sr-only" id="comments-title">评论</h2>
|
||||||
<div class="twikoo-preview" aria-label="Twikoo 评论预览">
|
<div class="twikoo-preview" aria-label="Twikoo 评论预览">
|
||||||
<p class="twikoo-preview-status">Twikoo 尚未配置</p>
|
<p class="twikoo-preview-status">Twikoo 尚未配置</p>
|
||||||
<div class="twikoo-preview-fields" aria-hidden="true">
|
<div class="twikoo-preview-fields" aria-hidden="true">
|
||||||
@@ -30,9 +30,8 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
|
|||||||
</section>}
|
</section>}
|
||||||
|
|
||||||
<style is:global>
|
<style is:global>
|
||||||
#comments { width: min(100%, var(--article-content-width)); margin: 4.375rem auto 0; }
|
#comments { width: 100%; margin: 0; font-family: var(--reading-font-family); }
|
||||||
#comments > h2 { margin: 0 0 1.5rem; padding-top: 1.375rem; border-top: 1px solid var(--color-border); color: var(--color-accent-strong); font-family: var(--reading-font-family); font-size: 1.5625rem; font-weight: 500; }
|
#twikoo-comments, #comments > #twikoo { color: var(--color-text); font-family: var(--reading-font-family); font-size: .94rem; }
|
||||||
#twikoo-comments, #comments > #twikoo { color: var(--color-text); font-size: .94rem; }
|
|
||||||
#twikoo-comments .tk-comments-title, #comments > #twikoo .tk-comments-title { margin: 0 0 18px; color: var(--color-text); font-family: var(--font-serif); font-size: 1.1rem; font-weight: 600; }
|
#twikoo-comments .tk-comments-title, #comments > #twikoo .tk-comments-title { margin: 0 0 18px; color: var(--color-text); font-family: var(--font-serif); font-size: 1.1rem; font-weight: 600; }
|
||||||
#twikoo-comments .tk-comment, #comments > #twikoo .tk-comment { padding: 1.375rem 0; border-bottom: 1px solid var(--color-border); }
|
#twikoo-comments .tk-comment, #comments > #twikoo .tk-comment { padding: 1.375rem 0; border-bottom: 1px solid var(--color-border); }
|
||||||
#twikoo-comments .tk-content, #twikoo-comments .tk-comment-content, #comments > #twikoo .tk-content, #comments > #twikoo .tk-comment-content { margin-top: .5rem; color: var(--color-text); line-height: 1.75; overflow-wrap: anywhere; }
|
#twikoo-comments .tk-content, #twikoo-comments .tk-comment-content, #comments > #twikoo .tk-content, #comments > #twikoo .tk-comment-content { margin-top: .5rem; color: var(--color-text); line-height: 1.75; overflow-wrap: anywhere; }
|
||||||
@@ -94,7 +93,7 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
|
|||||||
#comments > #twikoo .tk-submit-action-icon { color: var(--color-muted) !important; }
|
#comments > #twikoo .tk-submit-action-icon { color: var(--color-muted) !important; }
|
||||||
#comments > #twikoo .OwO-logo { color: var(--color-muted) !important; }
|
#comments > #twikoo .OwO-logo { color: var(--color-muted) !important; }
|
||||||
#comments > #twikoo .OwO-body { border: 1px solid var(--color-border) !important; border-radius: var(--radius-sm) !important; background: var(--color-surface) !important; color: var(--color-text) !important; box-shadow: var(--shadow-soft) !important; }
|
#comments > #twikoo .OwO-body { border: 1px solid var(--color-border) !important; border-radius: var(--radius-sm) !important; background: var(--color-surface) !important; color: var(--color-text) !important; box-shadow: var(--shadow-soft) !important; }
|
||||||
#comments > #twikoo .tk-send { min-width: 7rem !important; height: 2.25rem !important; border: 0 !important; border-radius: var(--radius-sm) !important; background: var(--color-accent) !important; color: var(--color-accent-contrast) !important; font-weight: 500 !important; }
|
#comments > #twikoo .tk-send { min-width: 7rem !important; height: 2.25rem !important; border: 0 !important; border-radius: var(--radius-sm) !important; background: var(--color-accent) !important; color: var(--color-accent-contrast) !important; font-family: var(--reading-font-family) !important; font-size: .875rem !important; font-weight: 500 !important; }
|
||||||
#comments > #twikoo .tk-send.is-disabled { opacity: .55 !important; }
|
#comments > #twikoo .tk-send.is-disabled { opacity: .55 !important; }
|
||||||
#comments > #twikoo .tk-preview { border: 1px solid var(--color-border) !important; border-radius: var(--radius-sm) !important; background: transparent !important; color: var(--color-muted) !important; }
|
#comments > #twikoo .tk-preview { border: 1px solid var(--color-border) !important; border-radius: var(--radius-sm) !important; background: transparent !important; color: var(--color-muted) !important; }
|
||||||
#comments > #twikoo .tk-comments-container { margin-top: 3rem !important; }
|
#comments > #twikoo .tk-comments-container { margin-top: 3rem !important; }
|
||||||
@@ -169,5 +168,5 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
|
|||||||
#comments > #twikoo .tk-replies .tk-comment > .tk-avatar { flex-basis: 1.75rem !important; width: 1.75rem !important; height: 1.75rem !important; margin-right: .5rem !important; }
|
#comments > #twikoo .tk-replies .tk-comment > .tk-avatar { flex-basis: 1.75rem !important; width: 1.75rem !important; height: 1.75rem !important; margin-right: .5rem !important; }
|
||||||
#comments > #twikoo .OwO .OwO-body { right: 0 !important; left: auto !important; width: min(18rem, 100vw - 2rem) !important; }
|
#comments > #twikoo .OwO .OwO-body { right: 0 !important; left: auto !important; width: min(18rem, 100vw - 2rem) !important; }
|
||||||
}
|
}
|
||||||
@media (max-width: 37.5rem) { #comments { margin-top: 3.25rem; } #twikoo-comments .tk-avatar, #twikoo-comments .tk-comment-avatar { width: 1.875rem; height: 1.875rem; } }
|
@media (max-width: 37.5rem) { #twikoo-comments .tk-avatar, #twikoo-comments .tk-comment-avatar { width: 1.875rem; height: 1.875rem; } }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
---
|
---
|
||||||
import { Send } from '@lucide/astro';
|
|
||||||
import { getWebmentionEndpoint } from '@/lib/webmentions';
|
import { getWebmentionEndpoint } from '@/lib/webmentions';
|
||||||
import { siteConfig } from '@/site.config';
|
import { siteConfig } from '@/site.config';
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
data-site-origin={new URL(siteConfig.site.url).origin}
|
data-site-origin={new URL(siteConfig.site.url).origin}
|
||||||
data-pagefind-ignore="all"
|
data-pagefind-ignore="all"
|
||||||
>
|
>
|
||||||
<h2 id="webmentions-title">WebMention</h2>
|
<h2 class="sr-only" id="webmentions-title">WebMention</h2>
|
||||||
|
|
||||||
<div class="webmentions-loading" data-webmentions-loading role="status" aria-label="正在读取 WebMention">
|
<div class="webmentions-loading" data-webmentions-loading role="status" aria-label="正在读取 WebMention">
|
||||||
<svg class="webmentions-loading-spinner" viewBox="25 25 50 50" aria-hidden="true">
|
<svg class="webmentions-loading-spinner" viewBox="25 25 50 50" aria-hidden="true">
|
||||||
@@ -56,10 +55,7 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
<div class="webmention-form-row">
|
<div class="webmention-form-row">
|
||||||
<input id="webmention-source" name="source" type="url" inputmode="url" autocomplete="url" placeholder="https://example.com/your-post" required />
|
<input id="webmention-source" name="source" type="url" inputmode="url" autocomplete="url" placeholder="https://example.com/your-post" required />
|
||||||
<input name="target" type="hidden" value={target} />
|
<input name="target" type="hidden" value={target} />
|
||||||
<button type="submit">
|
<button type="submit">发送</button>
|
||||||
<Send size={16} stroke-width={1.8} aria-hidden="true" />
|
|
||||||
<span>发送</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="webmention-form-status" data-webmention-form-status role="status" aria-live="polite"></p>
|
<p class="webmention-form-status" data-webmention-form-status role="status" aria-live="polite"></p>
|
||||||
</form>}
|
</form>}
|
||||||
@@ -67,18 +63,8 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.webmentions-shell {
|
.webmentions-shell {
|
||||||
width: min(100%, var(--article-content-width));
|
|
||||||
margin: 4.375rem auto 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.webmentions-shell > h2 {
|
|
||||||
margin: 0 0 1.5rem;
|
|
||||||
padding-top: 1.375rem;
|
|
||||||
border-top: 1px solid var(--color-border);
|
|
||||||
color: var(--color-accent-strong);
|
|
||||||
font-family: var(--reading-font-family);
|
font-family: var(--reading-font-family);
|
||||||
font-size: 1.5625rem;
|
font-size: .94rem;
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.webmentions-status,
|
.webmentions-status,
|
||||||
@@ -163,7 +149,7 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
:global(.webmention-reaction) {
|
:global(.webmention-reaction) {
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 2.25rem;
|
width: 2.25rem;
|
||||||
height: 2.25rem;
|
height: 2.125rem;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
@@ -254,7 +240,7 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
|
|
||||||
:global(.webmention-author) {
|
:global(.webmention-author) {
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
font-size: .875rem;
|
font-size: .8125rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
@@ -308,12 +294,15 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
.webmention-form input[type='url'] {
|
.webmention-form input[type='url'] {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
height: 2.5rem;
|
height: 2.125rem;
|
||||||
padding: .5rem .75rem;
|
padding: .438rem .525rem;
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--color-surface);
|
background: var(--color-surface);
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: .8125rem;
|
||||||
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.webmention-form input[type='url']:focus {
|
.webmention-form input[type='url']:focus {
|
||||||
@@ -326,15 +315,17 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: .4rem;
|
min-width: 7rem;
|
||||||
min-height: 2.5rem;
|
height: 2.25rem;
|
||||||
padding: .45rem .85rem;
|
padding: 0 .875rem;
|
||||||
border: 1px solid var(--color-accent-strong);
|
border: 0;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--color-accent);
|
background: var(--color-accent);
|
||||||
color: var(--color-accent-contrast);
|
color: var(--color-accent-contrast);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 600;
|
font-family: inherit;
|
||||||
|
font-size: .875rem;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.webmention-form button:disabled {
|
.webmention-form button:disabled {
|
||||||
@@ -349,8 +340,7 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
|
|
||||||
@media (max-width: 37.5rem) {
|
@media (max-width: 37.5rem) {
|
||||||
.webmentions-shell {
|
.webmentions-shell {
|
||||||
width: 100%;
|
font-size: .9rem;
|
||||||
margin-top: 3.25rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.webmention-form-row {
|
.webmention-form-row {
|
||||||
@@ -360,6 +350,7 @@ const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
|
|||||||
|
|
||||||
.webmention-form button {
|
.webmention-form button {
|
||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
|
min-width: 5.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import BaseLayout from '@/layouts/BaseLayout.astro';
|
|||||||
import Masthead from '@/components/Masthead.astro';
|
import Masthead from '@/components/Masthead.astro';
|
||||||
import { getContentCacheKey, getExcerpt, getPostCardImage, getPostPath, getPostTaxonomy, getPublicPosts, slugify } from '@/lib/content';
|
import { getContentCacheKey, getExcerpt, getPostCardImage, getPostPath, getPostTaxonomy, getPublicPosts, slugify } from '@/lib/content';
|
||||||
import { siteConfig } from '@/site.config';
|
import { siteConfig } from '@/site.config';
|
||||||
import TwikooComments from '@/components/TwikooComments.astro';
|
import EngagementTabs from '@/components/EngagementTabs.astro';
|
||||||
import TableOfContents from '@/components/TableOfContents.astro';
|
import TableOfContents from '@/components/TableOfContents.astro';
|
||||||
import Mermaid from '@/components/Mermaid.astro';
|
import Mermaid from '@/components/Mermaid.astro';
|
||||||
import ImageLightbox from '@/components/ImageLightbox.astro';
|
import ImageLightbox from '@/components/ImageLightbox.astro';
|
||||||
import Webmentions from '@/components/Webmentions.astro';
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = await getPublicPosts();
|
const posts = await getPublicPosts();
|
||||||
return posts.map((post, index) => ({
|
return posts.map((post, index) => ({
|
||||||
@@ -49,8 +48,11 @@ const dateText = `${date.year} 年 ${date.month} 月 ${date.day} 日`;
|
|||||||
{older ? <a class="grid min-h-24 content-center p-4 no-underline sm:border-r sm:border-line" href={getPostPath(older)}><span class="text-xs text-subtle">上一篇</span><strong class="mt-1 font-sans text-base font-normal">{older.data.title}</strong></a> : <span class="grid min-h-24 content-center p-4 sm:border-r sm:border-line"><span class="text-xs text-subtle">上一篇</span><strong class="mt-1 font-sans text-base font-normal">没有更多了</strong></span>}
|
{older ? <a class="grid min-h-24 content-center p-4 no-underline sm:border-r sm:border-line" href={getPostPath(older)}><span class="text-xs text-subtle">上一篇</span><strong class="mt-1 font-sans text-base font-normal">{older.data.title}</strong></a> : <span class="grid min-h-24 content-center p-4 sm:border-r sm:border-line"><span class="text-xs text-subtle">上一篇</span><strong class="mt-1 font-sans text-base font-normal">没有更多了</strong></span>}
|
||||||
{newer ? <a class="grid min-h-24 content-center border-t border-line p-4 no-underline sm:border-t-0 sm:text-right" href={getPostPath(newer)}><span class="text-xs text-subtle">下一篇</span><strong class="mt-1 font-sans text-base font-normal">{newer.data.title}</strong></a> : <span class="grid min-h-24 content-center border-t border-line p-4 sm:border-t-0 sm:text-right"><span class="text-xs text-subtle">下一篇</span><strong class="mt-1 font-sans text-base font-normal">没有更多了</strong></span>}
|
{newer ? <a class="grid min-h-24 content-center border-t border-line p-4 no-underline sm:border-t-0 sm:text-right" href={getPostPath(newer)}><span class="text-xs text-subtle">下一篇</span><strong class="mt-1 font-sans text-base font-normal">{newer.data.title}</strong></a> : <span class="grid min-h-24 content-center border-t border-line p-4 sm:border-t-0 sm:text-right"><span class="text-xs text-subtle">下一篇</span><strong class="mt-1 font-sans text-base font-normal">没有更多了</strong></span>}
|
||||||
</nav>
|
</nav>
|
||||||
<Webmentions target={new URL(Astro.url.pathname, siteConfig.site.url).href} />
|
<EngagementTabs
|
||||||
<TwikooComments enabled={post.data.comments} path={Astro.url.pathname} />
|
commentsEnabled={post.data.comments}
|
||||||
|
path={Astro.url.pathname}
|
||||||
|
target={new URL(Astro.url.pathname, siteConfig.site.url).href}
|
||||||
|
/>
|
||||||
</article>
|
</article>
|
||||||
<Mermaid enabled={post.data.mermaid} />
|
<Mermaid enabled={post.data.mermaid} />
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user