Skip to content

Commit

Permalink
支持移动设备
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Jan 1, 2025
1 parent b38fde6 commit 2d7ea07
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 85 deletions.
1 change: 1 addition & 0 deletions docs/content/getting-started/create-site/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: 创建网站
icon: folder-plus
---

安装 PageForge 后,你可以使用它来创建你的网站。您需要跳转到需要创建网站的文件夹,该文件夹必须是一个空文件夹。然后,您可以使用 PageForge 的命令行工具来创建网站。
Expand Down
1 change: 1 addition & 0 deletions docs/content/getting-started/customization.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: 自定义网站
icon: dessert
---

PageForge 提供了一些可选的自定义选项,以满足不同的需求。
Expand Down
1 change: 1 addition & 0 deletions docs/content/getting-started/get-started.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: 快速上手
icon: crosshair
---

PageForge 是一款现代化的静态页面生成与部署平台,旨在帮助用户快速创建精美的静态网站,并一键部署到 GitHub Pages。 无论是个人博客、项目文档还是企业官网,PageForge 都能让你轻松实现高效构建、智能部署和即时上线。
Expand Down
1 change: 1 addition & 0 deletions docs/content/getting-started/publish-site.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: 发布网站
icon: upload
---

在 git 存储库中托管项目文档的好处是能够在推送新更改时自动部署它。PageForge 将帮助您让这一切变得非常简单。
Expand Down
2 changes: 1 addition & 1 deletion templates/components/span-code.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = function template(item) {
return `
<code class="bg-gray-100 text-gray-900 px-1.5 py-0.5 rounded text-sm font-mono mx-1 inline">${item.text}</code>
<code class="bg-gray-100 text-gray-900 px-1.5 py-0.5 rounded text-sm font-mono mx-1 inline break-words whitespace-pre-wrap">${item.text}</code>
`;
};
12 changes: 4 additions & 8 deletions templates/components/tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,24 @@ module.exports = function tabs({tabs}) {

// 生成 tab 按钮 HTML
const tabButtons = tabs.map((tab, index) => `
<button
<button role="tab"
class="px-4 py-2 text-sm font-medium border-b-2 transition-colors duration-200
${index === 0 ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'}
focus:outline-none"
onclick="switchTab(event, '${tabGroupId}', ${index})"
role="tab"
aria-selected="${index === 0 ? 'true' : 'false'}"
aria-controls="${tabGroupId}-panel-${index}"
id="${tabGroupId}-tab-${index}"
>
id="${tabGroupId}-tab-${index}">
${tab.title}
</button>
`).join('');

// 生成 tab 内容 HTML
const tabPanels = tabs.map((tab, index) => `
<div
class="p-4 ${index === 0 ? '' : 'hidden'}"
<div class="p-4 ${index === 0 ? '' : 'hidden'}"
role="tabpanel"
aria-labelledby="${tabGroupId}-tab-${index}"
id="${tabGroupId}-panel-${index}"
>
id="${tabGroupId}-panel-${index}">
${tab.content}
</div>
`).join('');
Expand Down
82 changes: 52 additions & 30 deletions templates/includes/footer.ejs
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
<footer class="bg-gray-50 dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700">
<div class="mx-auto w-full max-w-screen-xl p-4 py-6 lg:py-8">
<div class="md:flex md:justify-between">
<div class="mb-6 md:mb-0 w-1/3">
<div class="flex flex-col md:flex-row md:justify-between gap-8">
<!-- Logo 和描述部分 -->
<div class="md:w-1/3">
<% if (site.logo) { %>
<a href="/" class="flex items-center">
<img src="<%= basePath %>/<%= site.logo || '/assets/logo.svg' %>"
alt="<%= site.title %>"
class="h-12 me-3">
</a>
<a href="/" class="text-xl font-bold text-gray-900 dark:text-white hover:text-gray-700 dark:hover:text-gray-200 transition-colors">
<%= !site.hiddenTitle ? site.title : '' %>
</a>
<div class="flex flex-col sm:flex-row items-start sm:items-center gap-3">
<a href="/" class="flex items-center">
<img src="<%= basePath %>/<%= site.logo || '/assets/logo.svg' %>"
alt="<%= site.title %>"
class="h-12">
</a>
<a href="/" class="text-xl font-bold text-gray-900 dark:text-white hover:text-gray-700 dark:hover:text-gray-200 transition-colors">
<%= !site.hiddenTitle ? site.title : '' %>
</a>
</div>
<% } %>

<div class="mt-2 text-sm text-gray-500 dark:text-gray-400">
<div class="mt-4 text-sm text-gray-500 dark:text-gray-400">
<%= site.description %>
</div>
</div>

<!-- 链接部分 -->
<% if (locals.footer && locals.footer.links) { %>
<div class="grid grid-cols-2 gap-8 sm:gap-20 sm:grid-cols-4">
<!-- 如果居中显示使用这个 -->
<!-- <div class="grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4 gap-6 sm:gap-8 lg:gap-12 text-center sm:text-left">-->
<div class="grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4 gap-6 sm:gap-8 lg:gap-12">
<% for(let category of footer.links) { %>
<div>
<% const categoryName = Object.keys(category)[0]; %>
<h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white"><%= categoryName %></h2>
<ul class="text-gray-500 dark:text-gray-400 font-medium">
<h2 class="mb-4 text-sm font-semibold text-gray-900 uppercase dark:text-white"><%= categoryName %></h2>
<ul class="text-gray-500 dark:text-gray-400 font-medium space-y-3">
<% for(let item of category[categoryName]) { %>
<li class="mb-4">
<a href="<%= item.href %>" class="hover:underline" target="_blank"><%= item.title %></a>
<li>
<a href="<%= item.href %>"
class="text-sm hover:text-gray-900 dark:hover:text-white hover:underline"
target="_blank">
<%= item.title %>
</a>
</li>
<% } %>
</ul>
Expand All @@ -39,43 +49,55 @@

<hr class="my-6 border-gray-200 sm:mx-auto dark:border-gray-700 lg:my-8"/>

<div class="sm:flex sm:items-center sm:justify-between">
<span class="text-sm text-gray-500 sm:text-center dark:text-gray-400"><%= locals.footer && locals.footer.copyright %></span>
<!-- 底部版权和社交链接 -->
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<span class="text-sm text-gray-500 dark:text-gray-400">
<%= locals.footer && locals.footer.copyright %>
</span>

<% if (locals.footer && locals.footer.social) { %>
<div class="flex mt-4 sm:justify-center sm:mt-0">
<div class="flex items-center gap-4">
<% if (footer.social.facebook) { %>
<a href="<%= footer.social.facebook.href %>" class="text-gray-500 hover:text-gray-900 dark:hover:text-white" target="_blank">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 8 19">
<a href="<%= footer.social.facebook.href %>"
class="text-gray-500 hover:text-gray-900 dark:hover:text-white"
target="_blank">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 8 19">
<path fill-rule="evenodd" d="M6.135 3H8V0H6.135a4.147 4.147 0 0 0-4.142 4.142V6H0v3h2v9.938h3V9h2.021l.592-3H5V3.591A.6.6 0 0 1 5.592 3h.543Z"
clip-rule="evenodd"/>
</svg>
<span class="sr-only"><%= footer.social.facebook.title %><</span>
<span class="sr-only"><%= footer.social.facebook.title %></span>
</a>
<% } %>
<% if (footer.social.discord) { %>
<a href="<%= footer.social.discord.href %>" class="text-gray-500 hover:text-gray-900 dark:hover:text-white ms-5" target="_blank">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 21 16">
<a href="<%= footer.social.discord.href %>"
class="text-gray-500 hover:text-gray-900 dark:hover:text-white"
target="_blank">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 21 16">
<path d="M16.942 1.556a16.3 16.3 0 0 0-4.126-1.3 12.04 12.04 0 0 0-.529 1.1 15.175 15.175 0 0 0-4.573 0 11.585 11.585 0 0 0-.535-1.1 16.274 16.274 0 0 0-4.129 1.3A17.392 17.392 0 0 0 .182 13.218a15.785 15.785 0 0 0 4.963 2.521c.41-.564.773-1.16 1.084-1.785a10.63 10.63 0 0 1-1.706-.83c.143-.106.283-.217.418-.33a11.664 11.664 0 0 0 10.118 0c.137.113.277.224.418.33-.544.328-1.116.606-1.71.832a12.52 12.52 0 0 0 1.084 1.785 16.46 16.46 0 0 0 5.064-2.595 17.286 17.286 0 0 0-2.973-11.59ZM6.678 10.813a1.941 1.941 0 0 1-1.8-2.045 1.93 1.93 0 0 1 1.8-2.047 1.919 1.919 0 0 1 1.8 2.047 1.93 1.93 0 0 1-1.8 2.045Zm6.644 0a1.94 1.94 0 0 1-1.8-2.045 1.93 1.93 0 0 1 1.8-2.047 1.918 1.918 0 0 1 1.8 2.047 1.93 1.93 0 0 1-1.8 2.045Z"/>
</svg>
<span class="sr-only"><%= footer.social.discord.title %><</span>
<span class="sr-only"><%= footer.social.discord.title %></span>
</a>
<% } %>
<% if (footer.social.twitter) { %>
<a href="<%= footer.social.twitter.href %>" class="text-gray-500 hover:text-gray-900 dark:hover:text-white ms-5" target="_blank">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 17">
<a href="<%= footer.social.twitter.href %>"
class="text-gray-500 hover:text-gray-900 dark:hover:text-white"
target="_blank">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 17">
<path fill-rule="evenodd"
d="M20 1.892a8.178 8.178 0 0 1-2.355.635 4.074 4.074 0 0 0 1.8-2.235 8.344 8.344 0 0 1-2.605.98A4.13 4.13 0 0 0 13.85 0a4.068 4.068 0 0 0-4.1 4.038 4 4 0 0 0 .105.919A11.705 11.705 0 0 1 1.4.734a4.006 4.006 0 0 0 1.268 5.392 4.165 4.165 0 0 1-1.859-.5v.05A4.057 4.057 0 0 0 4.1 9.635a4.19 4.19 0 0 1-1.856.07 4.108 4.108 0 0 0 3.831 2.807A8.36 8.36 0 0 1 0 14.184 11.732 11.732 0 0 0 6.291 16 11.502 11.502 0 0 0 17.964 4.5c0-.177 0-.35-.012-.523A8.143 8.143 0 0 0 20 1.892Z"
clip-rule="evenodd"/>
</svg>
<span class="sr-only"><%= footer.social.twitter.title %><</span>
<span class="sr-only"><%= footer.social.twitter.title %></span>
</a>
<% } %>
<% if (footer.social.github) { %>
<a href="<%= footer.social.github.href %>" class="text-gray-500 hover:text-gray-900 dark:hover:text-white ms-5" target="_blank">
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
<a href="<%= footer.social.github.href %>"
class="text-gray-500 hover:text-gray-900 dark:hover:text-white"
target="_blank">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M10 .333A9.911 9.911 0 0 0 6.866 19.65c.5.092.678-.215.678-.477 0-.237-.01-1.017-.014-1.845-2.757.6-3.338-1.169-3.338-1.169a2.627 2.627 0 0 0-1.1-1.451c-.9-.615.07-.6.07-.6a2.084 2.084 0 0 1 1.518 1.021 2.11 2.11 0 0 0 2.884.823c.044-.503.268-.973.63-1.325-2.2-.25-4.516-1.1-4.516-4.9A3.832 3.832 0 0 1 4.7 7.068a3.56 3.56 0 0 1 .095-2.623s.832-.266 2.726 1.016a9.409 9.409 0 0 1 4.962 0c1.89-1.282 2.717-1.016 2.717-1.016.366.83.402 1.768.1 2.623a3.827 3.827 0 0 1 1.02 2.659c0 3.807-2.319 4.644-4.525 4.889a2.366 2.366 0 0 1 .673 1.834c0 1.326-.012 2.394-.012 2.72 0 .263.18.572.681.475A9.911 9.911 0 0 0 10 .333Z"
clip-rule="evenodd"/>
Expand Down
96 changes: 75 additions & 21 deletions templates/includes/header.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ function isPathInNavItem(currentPath, navItem) {
%>

<header>
<nav class="fixed top-0 w-full bg-white dark:bg-gray-800 border-b z-10">
<nav class="fixed top-0 w-full bg-white dark:bg-gray-800 border-b z-40">
<div class="max-w-screen-xl px-4 mx-auto 2xl:px-0">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-8">
<div class="flex items-center justify-between h-16">
<div class="flex items-center justify-between flex-1 lg:flex-none">
<div class="flex items-center space-x-4 shrink-0">
<% if (site.logo) { %>
<a href="/" class="flex items-center">
Expand All @@ -46,26 +46,80 @@ function isPathInNavItem(currentPath, navItem) {
</a>
</div>

<ul class="hidden lg:flex items-center justify-start gap-6 md:gap-8 py-3 sm:justify-center">
<% for(let item of nav) { %>
<li class="shrink-0">
<a href="<%= item.href %>"
class="inline-flex items-center rounded-lg justify-center px-4 py-3
text-sm font-medium leading-none dark:text-white
<%=
isPathInNavItem(page.path, item)
? 'text-blue-600 dark:text-blue-400 bg-blue-50/80 dark:bg-blue-900/20 font-medium'
: 'hover:text-gray-900 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-800/40'
%>">
<%= item.title %>
</a>
</li>
<% } %>
</ul>
<!-- 移动端菜单按钮 -->
<button type="button"
class="lg:hidden p-2 rounded-md text-gray-600 hover:text-gray-900 hover:bg-gray-100 dark:text-gray-300 dark:hover:text-white dark:hover:bg-gray-700"
onclick="document.getElementById('mobile-menu').classList.toggle('hidden');
this.querySelector('svg:first-child').classList.toggle('hidden');
this.querySelector('svg:last-child').classList.toggle('hidden');">
<!-- 菜单图标 -->
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
</svg>
<!-- 关闭图标 -->
<svg class="h-6 w-6 hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>

<!-- 桌面端导航 -->
<ul class="hidden lg:flex items-center justify-start gap-6 md:gap-8 py-3 sm:justify-center">
<% for(let item of nav) { %>
<li class="shrink-0">
<a href="<%= item.href %>"
class="inline-flex items-center rounded-lg justify-center px-4 py-3
text-sm font-medium leading-none dark:text-white
<%=
isPathInNavItem(page.path, item)
? 'text-blue-600 dark:text-blue-400 bg-blue-50/80 dark:bg-blue-900/20 font-medium'
: 'hover:text-gray-900 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-800/40'
%>">
<%= item.title %>
</a>
</li>
<% } %>
</ul>

<!-- 仓库链接 -->
<div class="hidden lg:block">
<%- include('./repo') %>
</div>
</div>
</div>

<%- include('./repo') %>
<!-- 移动端菜单 -->
<div class="hidden lg:hidden" id="mobile-menu">
<div class="px-2 pt-2 pb-3 space-y-1 border-t dark:border-gray-700">
<% for(let item of nav) { %>
<a href="<%= item.href %>"
class="block px-3 py-2 rounded-md text-base font-medium
<%= isPathInNavItem(page.path, item)
? 'text-blue-600 dark:text-blue-400 bg-blue-50/80 dark:bg-blue-900/20'
: 'text-gray-700 dark:text-gray-200 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-gray-700'
%>">
<%= item.title %>
</a>
<% } %>
<!-- 移动端的仓库链接 -->
<div class="px-3 py-2">
<%- include('./repo') %>
</div>
</div>
</div>
</nav>
</header>
</header>

<script>
// 点击外部区域关闭移动端菜单
document.addEventListener('click', function (event) {
const mobileMenu = document.getElementById('mobile-menu');
const menuButton = document.querySelector('button[onclick*="mobile-menu"]');
if (!mobileMenu.contains(event.target) && !menuButton.contains(event.target) && !mobileMenu.classList.contains('hidden')) {
mobileMenu.classList.add('hidden');
menuButton.querySelector('svg:first-child').classList.remove('hidden');
menuButton.querySelector('svg:last-child').classList.add('hidden');
}
});
</script>
Loading

0 comments on commit 2d7ea07

Please sign in to comment.