提交 95786fb7 编写于 作者: C codecalm

update dependencies, update seo

上级 f32a3660
import Header from '@/components/layout/Header';
import Footer from '@/components/layout/Footer';
export default function CoreLayout({
children
}: {
children: React.ReactNode,
}) {
return (
<>
<Header className="header-docs" />
<main className="main bg-white">{children}</main>
<Footer />
</>
);
}
import { notFound } from 'next/navigation';
import { allPages } from 'contentlayer/generated';
import { Metadata } from 'next';
import Mdx from '@/components/MDX';
interface PageProps {
......@@ -9,6 +9,20 @@ interface PageProps {
}
}
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const page = await getPageFromParams(params);
if (!page) {
return {};
}
return {
title: `${page.title}`,
description: page.description,
robots: page.robots,
};
}
async function getPageFromParams(params) {
const slug = params?.slug,
page = allPages.find((page) => page.slugAsParams === slug);
......
......@@ -2,7 +2,7 @@ import Link from 'components/Link';
import { allPosts } from 'contentlayer/generated';
export const metadata = {
title: 'Blog - Tabler',
title: 'Blog',
description: 'Stay in the loop with all things Tabler. We provide regular updates on new features, changelogs, and news, ensuring you never miss any of our software developments.',
};
......
......@@ -2,6 +2,11 @@ import { allChangelogs } from '@/.contentlayer/generated';
import Mdx from '@/components/MDX';
import { dateTemplate, distanceToNow, format } from '@/lib/date';
export const metadata = {
title: 'Changelog',
description: 'Discover the latest Tabler app updates and enhancements on our Changelog page. Stay informed and experience the best features!',
};
export default function ChangelogPage() {
const changelogs = allChangelogs
.sort((a, b) => {
......
......@@ -6,6 +6,12 @@ import DocsMenu from '@/components/DocsMenu';
// import Icon from "@/components/Icon";
export const metadata = {
title: 'Documentation',
template: '%s - Documentation',
description: 'Get started with Tabler, the one of world’s most popular framework for building responsive, mobile-first dashboards.',
};
export default function DocsLayout({ children /*, meta = {}, pageProps*/ }) {
// const docsMenu = getDocsMenu(),
// router = useRouter(),
......
// import { DocsPageHeader } from "@/components/page-header"
// import { DocsPager } from "@/components/pager"
// import { DashboardTableOfContents } from "@/components/toc"
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { allDocs } from 'contentlayer/generated';
import { name } from '@/config/site';
// import { getTableOfContents } from "@/lib/toc"
import Mdx from '@/components/MDX';
import TablerSponsorsBanner from '@/components/TablerSponsorsBanner';
import Link from 'next/link';
// import { env } from "@/env.mjs"
// import { absoluteUrl } from "@/lib/utils"
interface DocPageProps {
params: {
......@@ -39,35 +35,11 @@ export async function generateMetadata({
return {};
}
// const url = env.NEXT_PUBLIC_APP_URL
// const ogUrl = new URL(`${url}/api/og`)
// ogUrl.searchParams.set("heading", doc.description ?? doc.title)
// ogUrl.searchParams.set("type", "Documentation")
// ogUrl.searchParams.set("mode", "dark")
return {
title: doc.title,
title: `${doc.title} - Documentation - ${name}`,
description: doc.description,
openGraph: {
title: doc.title,
description: doc.description,
type: 'article',
// url: absoluteUrl(doc.slug),
// images: [
// {
// url: ogUrl.toString(),
// width: 1200,
// height: 630,
// alt: doc.title,
// },
// ],
},
twitter: {
card: 'summary_large_image',
title: doc.title,
description: doc.description,
// images: [ogUrl.toString()],
},
};
}
......@@ -91,6 +63,25 @@ export default async function DocPage({ params }: DocPageProps) {
return (
<>
<nav aria-label="breadcrumbs" className="breadcrumb mb-6">
<ul className="breadcrumb-list">
<li className="breadcrumb-item">
<Link href="/" className="breadcrumb-link">
Home
</Link>
</li>
<li className="breadcrumb-item">
<Link href="/docs" className="breadcrumb-link">
Documentation
</Link>
</li>
<li className="breadcrumb-item">
<Link href={`/docs/${params.slug.join('/')}`} className="breadcrumb-link">
{doc.title}
</Link>
</li>
</ul>
</nav>
<div className="markdown">
{/* {category && (
<div className="h-subheader text-primary">{category}</div>
......
......@@ -7,6 +7,11 @@ import { emailsCount } from '@/config/site';
import CTABannerEmails from '@/components/CTABAnnerEmails';
import clsx from 'clsx';
export const metadata = {
title: 'Emails Gallery',
description: 'Tabler Emails is a set of responsive email templates for marketing, transactional and automated emails.',
};
export default function EmailsGalleryPage() {
return (
<>
......@@ -62,17 +67,3 @@ export default function EmailsGalleryPage() {
</>
);
}
// export async function getStaticProps() {
// return {
// props: {
// brand: 'tabler-emails',
// menu: 'emails',
// meta: {
// bodyClassName: 'body-gradient',
// title: `Tabler Emails: ${emailsCount} unique HTML email designs`,
// description: `See how our emails look. Choose your favorite from among ${emailsCount} carefully prepared emails.`,
// },
// },
// }
// }
......@@ -9,7 +9,7 @@ import React from 'react';
import Slider from '@/components/Slider';
export const metadata = {
title: 'Tabler Emails',
title: '54 eye-catching, customizable and responsive email templates',
description: 'Tabler Emails is a set of responsive email templates for marketing, transactional and automated emails.',
};
......@@ -295,18 +295,3 @@ export default function EmailsPage() {
</>
);
}
// export async function getStaticProps() {
// return {
// props: {
// brand: 'tabler-emails',
// menu: 'emails',
// meta: {
// bodyClassName: 'body-gradient',
// title: 'Tabler Emails: Responsive Newsletters and Email templates design',
// description:
// 'Look great in every inbox! Compose newsletter, e-commerce messages, reset password and any other email in less than 5 minutes',
// },
// },
// }
// }
import ResponsiveImage from '@/components/ResponsiveImage';
import features from '@/data/features';
export const metadata = {
title: 'Tabler Features',
description: 'Explore the powerful and versatile features of Tabler. Simplify tasks, boost productivity, and enhance your experience. Discover Tabler today!',
};
export default function FeaturesPage() {
return (
<section className="section">
......@@ -39,14 +44,3 @@ export default function FeaturesPage() {
</section>
);
}
// export async function getStaticProps() {
// return {
// props: {
// menu: 'ui',
// meta: {
// bodyClassName: 'body-gradient',
// },
// },
// }
// }
'use client';
import { notFound, useRouter } from 'next/navigation';
import { useClipboard } from '@/hooks';
import clsx from 'clsx';
......
......@@ -3,6 +3,11 @@ import { allGuides } from 'contentlayer/generated';
import { format } from '@/lib/date';
import Link from '@/components/Link';
export const metadata = {
title: 'Guides',
description: 'Learn how to use Tabler effectively with our comprehensive guides. Master the app and streamline your workflow today.',
};
export default async function GuidesPage() {
return (
<section className="section">
......
......@@ -11,6 +11,11 @@ import ResponsiveImage from '@/components/ResponsiveImage';
import SectionDivider from '@/components/SectionDivider';
import HeroIcons from '@/components/layout/hero/UiIcons';
export const metadata = {
title: 'Tabler Icons',
description: 'Explore our Tabler Icons package. Enhance your designs with a diverse collection of stunning icons.',
};
// const IconsInstallation = () => {
// return (
// <section className="section section-light">
......@@ -139,6 +144,7 @@ const IconsCategories = () => {
delete iconsGroupedByCategory['Database'];
delete iconsGroupedByCategory['Building'];
delete iconsGroupedByCategory['Logic'];
delete iconsGroupedByCategory['Currency'];
delete iconsGroupedByCategory['Animals'];
return (
......@@ -183,17 +189,3 @@ export default function IconsPage() {
</>
);
}
// export async function getStaticProps() {
// return {
// props: {
// brand: 'tabler-icons',
// menu: 'icons',
// meta: {
// bodyClassName: 'body-gradient',
// title: `Tabler Icons: over ${iconsCountRounded} free and open source vector icons for web design`,
// description: `${iconsCount} free and open source SVG icons designed with attention to detail to make your design stand out. Highly customizable. No attribution required. For commercial use.`,
// },
// },
// }
// }
'use client';
import React, { useState } from 'react';
import React from 'react';
import Link from 'next/link';
import questions from '@/data/faq.json';
import { componentsCount, emailsPrice, iconsUrl } from '@/config/site';
import { componentsCount, iconsUrl } from '@/config/site';
import Features from '@/components/Features';
import Icon from '@/components/Icon';
import ResponsiveImage from '@/components/ResponsiveImage';
import SectionDivider from '@/components/SectionDivider';
import Shape from '@/components/Shape';
......@@ -14,6 +11,11 @@ import Testimonials from '@/components/layout/Testimonials';
import TestimonialsShare from '@/components/layout/TestimonialsShare';
import HeroUi from '@/components/layout/hero/Ui';
export const metadata = {
title: 'Premium dashboard template with responsive and high quality UI',
description: 'Tabler comes with tons of well-designed components and features. Start your adventure with Tabler and make your dashboard great again. For free!',
};
const benefits = [
'Fully responsive',
'Based on Bootstrap 5',
......@@ -27,54 +29,6 @@ const benefits = [
'Premium vector icons',
];
const Modal = () => {
const [modalVisible, setModalVisible] = useState(true);
return (
modalVisible && (
<div className="modal-backdrop">
<div className="modal modal-wide">
<div
className="modal-close"
onClick={() => setModalVisible(false)}
>
<Icon name="x" />
</div>
<div className="row g-0">
<div className="col-6">
<div
className="ratio ratio-1x1 rounded-left"
style={{
backgroundColor: '#fff',
backgroundImage: 'url(https://source.unsplash.com/random/478x478/?landscape)',
}}
/>
</div>
<div className="col">
<div className="modal-body d-flex flex-column h-100">
<h3 className="modal-title">Modal title</h3>
<div className="text-muted">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cum
eius eligendi error facilis fugiat laboriosam omnis quam
soluta? Adipisci aliquam iste numquam, optio perferendis
possimus quae ratione rerum soluta voluptatibus.
</div>
<a
href="#"
className="mt-auto btn btn-primary btn-block"
onClick={() => setModalVisible(false)}
>
Buy for $$
{emailsPrice}
</a>
</div>
</div>
</div>
</div>
</div>
)
);
};
const FAQ = () => {
return (
......@@ -699,18 +653,3 @@ export default async function HomePage() {
</>
);
}
// export async function getStaticProps() {
// return {
// props: {
// menu: "ui",
// meta: {
// bodyClassName: "body-gradient",
// title:
// "Tabler: Premium dashboard template with responsive and high quality UI",
// description:
// "Tabler comes with tons of well-designed components and features. Start your adventure with Tabler and make your dashboard great again. For free!",
// },
// },
// }
// }
......@@ -2,6 +2,11 @@ import { pricingPlansPersonal, pricingPlanTeam } from '@/config/pricing';
import clsx from 'clsx';
import Icon from '@/components/Icon';
export const metadata = {
title: 'Tabler Pricing',
description: 'Check out our pricing plans and choose the best option for your needs. Find affordable and flexible solutions for our products and services.',
};
const PricingCards = () => {
return (
<div className="pricing">
......
export const metadata = {
title: 'Sponsorship Options',
description: 'Tabler Sponsorship options',
};
export default function SponsorshipPage() {
return false;
}
import Shape from '@/components/Shape';
export const metadata = {
title: 'Support',
description: 'Get help and assistance on our Support page. Find answers to your queries and resolve issues quickly. We\'re here to support you.',
};
export default function Support() {
return (
<section className="section">
......@@ -62,15 +67,3 @@ export default function Support() {
</section>
);
}
// export async function getStaticProps() {
// return {
// props: {
// menu: 'ui',
// meta: {
// bodyClassName: 'body-gradient',
// title: 'Support',
// },
// },
// }
// }
import Testimonials from '@/components/layout/Testimonials';
export const metadata = {
title: 'Testimonials',
description: 'Read what our customers are saying about us. Explore testimonials and see why people love our products and services.',
};
export default function TestimonialsPage() {
return <>
<section className="section">
......@@ -15,4 +20,4 @@ export default function TestimonialsPage() {
</div>
</section>
</>;
}
\ No newline at end of file
}
......@@ -6,8 +6,9 @@ import PageProgress from '@/components/PageProgress';
export const metadata = {
title: {
default: name,
template: `%s | ${name}`,
template: `%s - ${name}`,
},
metadataBase: new URL(uiUrl),
description: description,
keywords: [
'css',
......@@ -51,7 +52,7 @@ export const metadata = {
},
twitter: {
card: 'summary_large_image',
images: [`${uiUrl}/og.jpg`],
images: ['og.jpg'],
creator: `@${creator}`,
},
icons: {
......@@ -59,34 +60,23 @@ export const metadata = {
shortcut: '/favicon-16x16.png',
apple: '/apple-touch-icon.png',
},
// manifest: `${uiUrl}/site.webmanifest`,
};
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
export default function RootLayout({ children }: { children: React.ReactNode; }) {
return (
<html lang="en">
<head>
<script
defer
data-api="/stats/api/event"
data-domain="tabler.io,tabler"
src="/stats/js/script.js"
/>
<script>
{
'window.plausible=window.plausible||function(){(window.plausible.q=window.plausible.q||[]).push(arguments)}'
}
</script>
{process.env.NODE_ENV !== 'development' && (
<>
<script defer data-api="/stats/api/event" data-domain="tabler.io,tabler" src="/stats/js/script.js" />
<script>{'window.plausible=window.plausible||function(){(window.plausible.q=window.plausible.q||[]).push(arguments)}'}</script>
</>
)}
</head>
<body className="body-gradient">
<body>
<PageProgress />
{children}
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
{/* <script src="https://cdn.paritydeals.com/banner.js" defer /> */}
<script src="https://assets.lemonsqueezy.com/lemon.js" defer />
</body>
</html>
......
......@@ -17,7 +17,8 @@ import IconsCount from '@/components/mdx/IconsCount';
import Image from '@/components/mdx/Image';
import PaymentsTable from '@/components/mdx/PaymentsTable';
import TablerLogos from '@/components/mdx/TablerLogos';
import { Tab, Tabs, TabsPackage } from '@/components/mdx/Tabs';
import { Tab, Tabs } from '@/components/mdx/Tabs';
import { TabsPackage } from '@/components/mdx/TabsPackage';
import { TipBad, TipGood, TipChanges } from '@/components/mdx/Tips';
import { OptionDescription, OptionTitle, OptionsTable } from '@/components/mdx/OptionsTable';
......
'use client';
import { Fragment, PropsWithChildren, useEffect, useState } from 'react';
import { Fragment, MutableRefObject, PropsWithChildren, RefObject, useCallback, useEffect, useRef, useState } from 'react';
import { Dialog, Popover } from '@headlessui/react';
import clsx from 'clsx';
import { componentsRounded, iconsCountRounded, sponsorsUrl, uiGithubUrl } from '@/config/site';
import { banner, componentsRounded, iconsCountRounded, sponsorsUrl, uiGithubUrl } from '@/config/site';
import Icon from '@/components/Icon';
import GoToTop from '@/components/layout/GoToTop';
import Link from '@/components/Link';
import NavLink from '@/components/NavLink';
import Shape from '@/components/Shape';
// import { useRouter } from 'next/router'
const NavDropdown = ({ title, children, active, footer = false }) => {
......@@ -100,11 +94,7 @@ const menuLinks = [
{
href: '/blog',
menu: 'blog',
title: (
<>
Blog
</>
),
title: <>Blog</>,
},
{
href: '/docs',
......@@ -145,14 +135,7 @@ const NavbarLink = (link, menu) => {
return (
<NavDropdown title={link.title} active={menu === link.menu}>
{link.children.map((link) => (
<Popover.Button
as={Link}
href={link.href || ''}
className="navbar-dropdown-menu-link"
key={link.title}
onClick={() => true}
{...link.props}
>
<Popover.Button as={Link} href={link.href || ''} className="navbar-dropdown-menu-link" key={link.title} onClick={() => true} {...link.props}>
<div className="row g-3">
<div className="col-auto">
<Shape icon={link.icon} />
......@@ -208,37 +191,52 @@ const SidebarLink = (link, menu, onClick) => {
);
};
const Navbar = ({
menu,
opened,
onClick,
...props
}: {
menu?: string
opened?: boolean
onClick?: (event: React.MouseEvent) => void,
className?: string,
}) => {
const Navbar = ({ menu, opened, onClick, ...props }: { menu?: string; opened?: boolean; onClick?: (event: React.MouseEvent) => void; className?: string }) => {
return (
<div className={clsx('navbar', opened && 'opened', props.className)}>
{menuLinks.map((link) => (
<Fragment key={link.menu}>
{NavbarLink(link, menu)}
</Fragment>
<Fragment key={link.menu}>{NavbarLink(link, menu)}</Fragment>
))}
</div>
);
};
export default function Header({ headerStatic, className, pageProps, ...props }:{
headerStatic?: boolean,
className?: string,
pageProps?: any,
}) {
const bannerId = 'tabler-icons-v2';
const Banner = () => {
const [showBanner, setShowBanner] = useState(false);
useEffect(() => {
if (window.localStorage.getItem(`banner-${banner.id}`) !== '1') {
setShowBanner(true);
}
}, []);
function closeBanner() {
localStorage.setItem(`banner-${banner.id}`, '1');
setShowBanner(false);
}
return (
banner.show &&
showBanner && (
<div className="banner">
<div className="container">
<div className="text-truncate">{banner.text}</div>
<a href={banner.link.href} className="ml-5 banner-link" target="_blank">
{banner.link.text}
</a>
</div>
<a onClick={closeBanner} className="banner-close">
<Icon name="x" />
</a>
</div>
)
);
};
export default function Header({ headerStatic, className, pageProps, ...props }: { headerStatic?: boolean; className?: string; pageProps?: any }) {
const [sticky, setSticky] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [showBanner, setShowBanner] = useState(false);
const pop = () => {
setSticky(window.pageYOffset > 0);
......@@ -252,59 +250,22 @@ export default function Header({ headerStatic, className, pageProps, ...props }:
setIsOpen(!isOpen);
}
function closeBanner() {
localStorage.setItem(`banner-${bannerId}`, '1');
setShowBanner(false);
}
useEffect(() => {
window.addEventListener('scroll', pop);
if (window.localStorage.getItem(`banner-${bannerId}`) !== '1') {
setShowBanner(true);
}
return () => window.removeEventListener('scroll', pop);
}, []);
// const router = useRouter()
return (
<>
{/* {showBanner && (
<div className="banner">
<div className="container">
<div className="text-truncate">
🎉 Tabler Icons v2.0 has been released: filled icons, new packages: React, Vue, Preact, Svelte, SolidJS
and more!
</div>
<a href="https://tabler-icons.io" className="ml-5 banner-link">
Learn more →
</a>
</div>
<a onClick={closeBanner} className="banner-close">
<Icon name="x" />
</a>
</div>
)} */}
<Banner />
<header
className={clsx(
'header',
// router.pathname.startsWith('/docs') && 'header-bordered',
headerStatic ? 'header-static' : '',
sticky && 'header-sticky',
className
// headerStatic ? 'header-static' : '',
// isVisible && 'header-sticky',
className,
)}
>
<div className="container" data-aos="fade-down">
<nav className="row items-center">
<div className="col-auto">
<Link
href="/"
className={clsx('logo'/*, pageProps.brand ? `logo-${pageProps.brand}` : ''*/)}
aria-label="Tabler"
/>
<Link href="/" className={clsx('logo' /*, pageProps.brand ? `logo-${pageProps.brand}` : ''*/)} aria-label="Tabler" />
</div>
<div className="col-auto ml-auto">
<div className="d-none md:d-block">
......
import { iconsCountRounded, iconsGithubUrl, iconsUrl } from '@/config/site';
import { iconsCount, iconsGithubUrl, iconsUrl } from '@/config/site';
import ResponsiveImage from '@/components/ResponsiveImage';
import Icon from '@/components/Icon';
import React from 'react';
......@@ -13,7 +13,7 @@ export default function LayoutHeroUiIcons() {
<div className="hero-subheader">Tabler Icons</div>
<h1 className="hero-title">Pixel-perfect icons that match your design</h1>
<p className="hero-description mt-4">
Over {iconsCountRounded} free, open source icons designed to make your website or app attractive, visually
{iconsCount} free, open source icons designed to make your website or app attractive, visually
consistent and simply beautiful.
</p>
<div className="mt-5 lg:mt-7">
......
......@@ -7,7 +7,6 @@ type Color = {
}
export default function ColorsTable({ name }: { name: string }) {
console.log(colors, name);
if (!colors[name]) {
return null;
}
......
......@@ -3,7 +3,6 @@
import clsx from 'clsx';
import { Tab as HTab } from '@headlessui/react';
import { Fragment } from 'react';
import { Pre } from '@/components/mdx/Code';
export function Tabs({ items, children }) {
return (
......@@ -24,24 +23,3 @@ export function Tab({ children }) {
return <HTab.Panel className="tab-content">{children}</HTab.Panel>;
}
export function TabsPackage({ name }) {
return (
<Tabs items={['yarn', 'npm', 'pnpm']}>
<Tab>
<Pre>
<code className="language-plaintext">yarn add {name}</code>
</Pre>
</Tab>
<Tab>
<Pre>
<code className="language-plaintext">npm install {name}</code>
</Pre>
</Tab>
<Tab>
<Pre>
<code className="language-plaintext">pnpm install {name}</code>
</Pre>
</Tab>
</Tabs>
);
}
import { Pre } from '@/components/mdx/Code';
import { Tab, Tabs } from '@/components/mdx/Tabs';
export function TabsPackage({ name }) {
return (
<Tabs items={['yarn', 'npm', 'pnpm']}>
<Tab>
<Pre>
<code className="language-plaintext">yarn add {name}</code>
</Pre>
</Tab>
<Tab>
<Pre>
<code className="language-plaintext">npm install {name}</code>
</Pre>
</Tab>
<Tab>
<Pre>
<code className="language-plaintext">pnpm install {name}</code>
</Pre>
</Tab>
</Tabs>
);
}
......@@ -11,7 +11,7 @@ export const companyGithubUrl = 'https://github.com/tabler';
export const companyTwitterUrl = 'https://twitter.com/codecalm';
export const companyDribbbleUrl = 'https://dribbble.com/codecalm';
export const uiUrl = process.env.NODE_ENV === 'development' ? 'http://localhost:3010' : 'https://tabler.io';
export const uiUrl = 'https://tabler.io';
export const uiVersion = uiConfig.version;
export const uiPackageName = '@tabler/core';
......@@ -35,8 +35,8 @@ export const uiCdnJS = `${uiCdnUrl}${uiVersion}/dist/js/tabler.min.js`;
export const emailsCount = 54;
export const emailsPrice = 29;
export const emailsDownloadUrl = 'https://gum.co/tabler-email?wanted=true';
export const emailsSampleDownloadUrl = 'https://gum.co/tabler-email-sample';
export const emailsDownloadUrl = 'https://tabler.lemonsqueezy.com/checkout/buy/44fd4bdb-6ca0-49eb-b887-ebafd080c7bc?embed=1&desc=0&discount=0&media=0';
export const emailsSampleDownloadUrl = 'https://tabler.lemonsqueezy.com/checkout/buy/2b777bc1-09f3-4465-b2a5-50ba14dcbe49?embed=1&desc=0&discount=0&media=0';
export const componentsCount = 100; //getAllComponents().length
export const componentsRounded = (() => {
......@@ -123,3 +123,16 @@ export const footerMenu = [
];
export const colors = ['muted', 'red', 'pink', 'grape', 'violet', 'indigo', 'blue', 'cyan', 'teal', 'green', 'lime', 'yellow', 'orange'];
//
// Banner
//
export const banner = {
show: true,
id: 'tabler-icons-v2-2',
text: '🎉 Tabler Icons v2.0 has been released: filled icons, new packages: React, Vue, Preact, Svelte, SolidJS and more!',
link: {
href: 'https://tabler-icons.io',
text: 'Learn more →',
},
};
---
title: About Tabler
bodyClassName: body-gradient
---
## Project maintenance
......
---
title: Tabler Products License
bodyClassName: body-gradient
---
This is a legal agreement between you, the Purchaser, and Tabler. Purchasing or downloading of any Tabler product (Tabler, Tabler Icons, Tabler PRO, Tabler Emails), constitutes your acceptance of the terms of this license, Tabler terms of service and Tabler private policy.
......
---
title: Privacy Policy
bodyClassName: body-gradient
---
Your privacy is critically important to us. At Tabler, we have a few fundamental principles:
......
---
title: Terms of service
bodyClassName: body-gradient
---
This is a legal agreement between you, the Purchaser, and Tabler. Purchasing or downloading of any Tabler product (Tabler Free, Tabler PRO, Tabler Email), constitutes your acceptance of the terms of this license, Tabler terms of service and Tabler private policy.
......
---
title: You don't vote for kings.
description: Why do you think that she is a witch? How do you know she is a witch? Well, I didn't vote for you. Where'd you get the coconuts? Why? We shall say 'Ni' again to you, if you do not appease us.
bodyClassName: body-gradient
robots: noindex, nofollow
---
I am your king. Well, I didn't vote for you. It's only a model. __…Are you suggesting that coconuts migrate?__ *Well, how'd you become king, then?* Well, how'd you become king, then?
......
import { defineDocumentType, makeSource } from "contentlayer/source-files"
// import rehypeAutolinkHeadings from "rehype-autolink-headings"
// import rehypePrettyCode from "rehype-pretty-code"
// import rehypeSlug from "rehype-slug"
// import remarkGfm from "remark-gfm"
import { remarkPlugins } from './mdx/remark'
import { rehypePlugins } from './mdx/rehype'
......@@ -214,6 +210,10 @@ export const Page = defineDocumentType(() => ({
bodyClassName: {
type: "string",
},
robots: {
type: "string",
default: null
},
hidden: {
type: "boolean",
default: false,
......@@ -224,6 +224,7 @@ export const Page = defineDocumentType(() => ({
export default makeSource({
contentDirPath: "./content",
contentDirExclude: ["docs/menu.json", "docs/.DS_Store"],
documentTypes: [
Page,
Doc,
......
import React from 'react';
const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect
typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
export default useIsomorphicLayoutEffect
export default useIsomorphicLayoutEffect;
......@@ -25,8 +25,8 @@
"@headlessui/react": "^1.7.15",
"@mdx-js/loader": "^2.3.0",
"@mdx-js/react": "2.3.0",
"@next/env": "^13.4.10",
"@next/mdx": "^13.4.10",
"@next/env": "^13.4.12",
"@next/mdx": "^13.4.12",
"@sindresorhus/slugify": "^2.2.1",
"@svgr/webpack": "^8.0.1",
"@tabler/icons": "^2.28.0",
......@@ -36,7 +36,7 @@
"@types/react": "18.2.15",
"@types/react-dom": "18.2.7",
"@vercel/analytics": "^1.0.1",
"@vercel/og": "^0.5.8",
"@vercel/og": "^0.5.9",
"acorn": "^8.10.0",
"acorn-jsx": "^5.3.2",
"aos": "^2.3.4",
......@@ -48,12 +48,9 @@
"dlv": "^1.1.3",
"eslint": "8.x",
"eslint-config-next": "13.4.10",
"favicons": "^7.1.3",
"feed": "^4.2.2",
"file-loader": "^6.2.0",
"front-matter": "^4.0.2",
"fs-extra": "^11.1.1",
"gray-matter": "^4.0.3",
"hast-util-raw": "^8.0.0",
"hast-util-to-html": "^8.0.4",
"html-loader": "^4.2.0",
......@@ -69,21 +66,19 @@
"mdx-annotations": "^0.1.3",
"minimatch": "^9.0.3",
"modern-async": "^1.1.3",
"next": "^13.4.10",
"next": "^13.4.12",
"next-auth": "^4.22.1",
"next-contentlayer": "^0.3.4",
"next-mdx-remote": "^4.4.1",
"next-sitemap": "^4.1.8",
"nextjs-toploader": "^1.4.2",
"opentype.js": "^1.3.4",
"postcss": "^8.4.26",
"postcss": "^8.4.27",
"prettier": "3.0.0",
"prismjs": "^1.29.0",
"react": "^18.2.0",
"react-children-utilities": "^2.9.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.45.1",
"react-infinite-scroll-component": "^6.1.0",
"react-syntax-highlighter": "^15.5.0",
"rehype-autolink-headings": "^6.1.1",
"rehype-external-links": "^2.1.0",
......@@ -105,11 +100,11 @@
"remark-smartypants": "^2.0.0",
"remark-toc": "^8.0.1",
"remark-unwrap-images": "^3.0.1",
"sass": "^1.63.6",
"sass": "^1.64.1",
"tinytime": "^0.2.6",
"typescript": "5.1.6",
"unist-util-visit": "^5.0.0",
"webpack": "^5.88.1",
"webpack": "^5.88.2",
"yaml": "^2.3.1",
"@types/debug": "^4.1.8",
"@types/eslint": "^8.44.0",
......
此差异已折叠。
.breadcrumb {
}
.breadcrumb-list {
list-style-type: none;
padding: 0;
margin: 0;
display: flex;
font-size: $font-size-h6;
}
.breadcrumb-item {
color: $color-muted-light;
&:not(:first-child)::before {
content: '›';
margin: 0 .5rem;
}
}
.breadcrumb-link {
color: $color-muted-light;
}
......@@ -195,6 +195,7 @@
align-items: center;
transition: .3s background-color, .3s height, .6s box-shadow, .3s background;
z-index: $zindex-header + 30;
background: $color-white;
}
.header-static,
......@@ -216,6 +217,11 @@
}
}
//
// Main
//
.main {
}
//
// Side
......
......@@ -16,6 +16,7 @@
@import 'avatars';
@import 'badges';
@import 'breadcrumb';
@import 'browser';
@import 'buttons';
@import 'blanks';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册