视频地址: https://www.bilibili.com/vide...

基础样式

如鼠标指针、背景图片等。

鼠标指针

* {
    cursor: url('/default.cur'), default;
}

a,
a *,
button,
button *,
.btn,
.btn *,
.prose .post-image {
    cursor: url('/pointer.cur'), pointer;
}

背景图片切换

@layer components {
  #background {
    @apply fixed inset-0 saturate-150 z-[-1];
    background: url('/images/bg.jpg') no-repeat center center fixed;
    background-size: cover;
    transition: all 0.25s ease-in-out;
    transform-style: preserve-3d;
  }
  #background.dark {
    @apply brightness-50 saturate-100;
    transform: rotate(-3deg) scale(1.2);
    /* scaleX(-1); */
  }
}

Header

Link 封装

locale-link:

import {
  Link,
  type LinkProps,
  NavLink,
  type NavLinkProps
} from '@remix-run/react';
import { useI18n } from 'remix-i18n';

export function LocaleLink({
  to,
  children,
  ...props
}: LinkProps & { to: string }) {
  const i18n = useI18n();
  const path = `/${i18n.locale()}${to}`;

  return (
    <Link to={path} {...props}>
      {children}
    </Link>
  );
}

export function LocaleNavLink({
  to,
  children,
  ...props
}: NavLinkProps & { to: string }) {
  const i18n = useI18n();
  const path = `/${i18n.locale()}${to}`;

  return (
    <NavLink to={path} {...props}>
      {children}
    </NavLink>
  );
}

router-link:

import { type NavLinkProps } from '@remix-run/react';
import clsx from 'classnames';
import { LocaleNavLink } from './locale-link';

export function RouteLink({
  children,
  to
}: Pick<NavLinkProps, 'children' | 'to'>) {
  return LocaleNavLink({
    to,
    className: ({ isActive }) =>
      clsx(isActive ? 'glass' : 'btn-ghost', 'btn btn-sm rounded-btn'),
    children
  });
}

header 组件:

import { useI18n } from 'remix-i18n';
import { LocaleLink } from './atom/locale-link';
import { RouteLink } from './atom/router-link';
import { ToggleLocale } from './atom/toggle-locale';
import { ToggleTheme } from './atom/toggle-theme';

export function Header() {
  const i18n = useI18n();
  const { t } = i18n;

  return (
    <header className='fixed w-full z-20 opacity-90 hover:opacity-100'>
      <div className='navbar mb-2 shadow-lg bg-neutral text-neutral-content'>
        <div className='px-2 mx-2 navbar-start'>
          <LocaleLink to='/'>
            <span className='text-lg font-bold'>Willin Wang</span>
          </LocaleLink>
        </div>
        <div className='hidden px-2 mx-2 navbar-center lg:flex'>
          <div className='flex items-stretch'>
            <RouteLink to='/'>{t('nav.home')}</RouteLink>
            <RouteLink to='/posts'>{t('nav.posts')}</RouteLink>
            <RouteLink to='/projects'>{t('nav.projects')}</RouteLink>
            <RouteLink to='/playground'>{t('nav.playground')}</RouteLink>
            <RouteLink to='/about'>{t('nav.about')}</RouteLink>
          </div>
        </div>
        <div className='navbar-end'>
          <ToggleTheme />
          <ToggleLocale />
        </div>
      </div>
    </header>
  );
}

Footer

// import { useMatches } from '@remix-run/react';
// import clsx from 'classnames';
import { useI18n } from 'remix-i18n';
import { LocaleLink } from './atom/locale-link';
import { Github, CSDN, Juejin, SegmentFault, WillinLogo, Zhihu } from './svg';

export function Footer() {
  const { t } = useI18n();
  // const matches = useMatches();

  return (
    <footer className='p-4 sm:p-6 bg-base-200 text-base-content opacity-90'>
      <div className='md:flex md:justify-between'>
        <div className='mb-6 md:mb-0'>
          <LocaleLink to='/'>
            <WillinLogo size='5em' />
          </LocaleLink>
        </div>
        <div className='grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3'>
          {/* <div className={clsx({ hidden: posts.length === 0 })}>
            <ul>
              {posts
                .filter((x) => x.type === 'pages')
                .map((page) => (
                  <li key={page.slug}>
                    <LocaleLink to={`/${page.slug}`}>{page.title}</LocaleLink>
                  </li>
                ))}
            </ul>
          </div> */}
          <div>
            <ul>
              <li>
                <LocaleLink to='/'>{t('nav.home')}</LocaleLink>
              </li>
              <li>
                <LocaleLink to='/posts'>{t('nav.posts')}</LocaleLink>
              </li>
              <li>
                <LocaleLink to='/playground'>{t('nav.playground')}</LocaleLink>
              </li>
            </ul>
          </div>

          {/* <div>
            <ul>
              <li className='mb-4'>
                <a
                  href='#'
                  target='_blank'
                  className='text-gray-600 hover:underline dark:text-gray-400'>
                  Privacy Policy
                </a>
              </li>
              <li>
                <a
                  href='#'
                  target='_blank'
                  className='text-gray-600 hover:underline dark:text-gray-400'>
                  Terms &amp; Conditions
                </a>
              </li>
            </ul>
          </div> */}
        </div>
      </div>
      <hr className='my-6 border-gray-200 sm:mx-auto dark:border-gray-700 lg:my-8' />
      <div className='sm:flex sm:items-center sm:justify-between'>
        <span className='text-sm text-gray-500 sm:text-center dark:text-gray-400'>
          Willin Wang <small>&copy; 2002 ~ {new Date().getFullYear()}.</small>
          <small>
            Made with ❤️ and{' '}
            <a
              href='http://remix.run'
              target='_blank'
              rel='noopener noreferrer'>
              Remix
            </a>{' '}
            |{' '}
            <a
              href='https://beian.miit.gov.cn/'
              target='_blank'
              rel='noopener noreferrer'>
              苏ICP备17011988号-1
            </a>
          </small>
        </span>
        <div className='flex mt-4 space-x-6 sm:justify-center sm:mt-0'>
          <a
            href='https://segmentfault.com/u/willin'
            target='_blank'
            className='hover:text-secondary'
            rel='noopener noreferrer'
            aria-label='SegmentFault'>
            <SegmentFault />
          </a>

          <a
            href='https://blog.csdn.net/jslygwx?type=blog'
            target='_blank'
            className='hover:text-secondary'
            rel='noopener noreferrer'
            aria-label='CSDN'>
            <CSDN />
          </a>
          <a
            href='https://www.zhihu.com/people/willin'
            target='_blank'
            className='hover:text-secondary'
            rel='noopener noreferrer'
            aria-label='知乎'>
            <Zhihu />
          </a>

          <a
            href='https://juejin.cn/user/1873223546052391'
            target='_blank'
            className='hover:text-secondary'
            rel='noopener noreferrer'
            aria-label='掘金'>
            <Juejin />
          </a>

          <a
            href='https://github.com/willin'
            target='_blank'
            className='hover:text-secondary'
            aria-label='Github'>
            <Github />
          </a>
        </div>
      </div>
    </footer>
  );
}

willin
213 声望12 粉丝

欢迎在各平台 Follow 我。