Adding BitsUI to use in place of MeltUI. Using pagination from BitsUI.

This commit is contained in:
Bradley Shellnut 2024-05-14 17:33:39 -07:00
parent 53504abf64
commit 442f36f18d
15 changed files with 3983 additions and 3137 deletions

View file

@ -1,3 +1,4 @@
/** @type { import("eslint").Linter.Config } */
module.exports = {
root: true,
extends: [

View file

@ -1,7 +1,9 @@
{
"useTabs": true,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "none",
"trailingComma": "all",
"bracketSpacing": true,
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],

View file

@ -20,46 +20,46 @@
"@iconify-icons/mdi": "^1.2.48",
"@iconify-icons/radix-icons": "^1.2.9",
"@iconify-icons/simple-icons": "^1.2.74",
"@melt-ui/pp": "^0.3.0",
"@playwright/test": "^1.43.1",
"@melt-ui/pp": "^0.3.2",
"@playwright/test": "^1.44.0",
"@resvg/resvg-js": "^2.6.2",
"@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/enhanced-img": "^0.2.0",
"@sveltejs/kit": "^2.5.6",
"@sveltejs/kit": "^2.5.7",
"@sveltejs/vite-plugin-svelte": "^3.1.0",
"@typescript-eslint/eslint-plugin": "^7.7.0",
"@typescript-eslint/parser": "^7.7.0",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"@zerodevx/svelte-img": "^2.1.0",
"autoprefixer": "^10.4.19",
"eslint": "^9.0.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.37.0",
"eslint-plugin-svelte": "^2.38.0",
"iconify-icon": "^2.1.0",
"just-intersect": "^4.3.0",
"mdsvex": "^0.11.0",
"mdsvex-relative-images": "^1.0.3",
"postcss": "^8.4.38",
"postcss-import": "^16.1.0",
"postcss-load-config": "^5.0.3",
"postcss-preset-env": "^9.5.5",
"postcss-load-config": "^5.1.0",
"postcss-preset-env": "^9.5.11",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.3",
"sass": "^1.75.0",
"sass": "^1.77.0",
"satori": "^0.10.13",
"satori-html": "^0.3.2",
"scrape-it": "^6.1.0",
"scrape-it": "^6.1.2",
"sharp": "^0.33.3",
"svelte": "^4.2.14",
"svelte-check": "^3.6.9",
"svelte": "^4.2.16",
"svelte-check": "^3.7.1",
"svelte-meta-tags": "^3.1.2",
"svelte-preprocess": "^5.1.3",
"svelte-preprocess": "^5.1.4",
"svelte-sequential-preprocessor": "^2.0.1",
"tslib": "^2.6.2",
"typescript": "^5.4.5",
"vanilla-lazyload": "^19.1.3",
"vite": "^5.2.8",
"vite-imagetools": "^7.0.1",
"vitest": "^1.5.0"
"vite": "^5.2.11",
"vite-imagetools": "^7.0.2",
"vitest": "^1.6.0"
},
"type": "module",
"dependencies": {
@ -67,7 +67,11 @@
"@sveltejs/adapter-vercel": "^5.3.0",
"@types/nprogress": "^0.2.3",
"@vercel/og": "^0.6.2",
"ioredis": "^5.3.2",
"nprogress": "^0.2.0"
"bits-ui": "^0.21.7",
"flexsearch": "^0.7.43",
"ioredis": "^5.4.1",
"lucide-svelte": "^0.378.0",
"nprogress": "^0.2.0",
"svelte-local-storage-store": "^0.6.4"
}
}

File diff suppressed because it is too large Load diff

View file

@ -19,6 +19,12 @@
</a>
<style lang="postcss">
a {
margin: 1rem 0;
padding: 0;
font-size: var(--bodyTextSize);
}
.show-icon {
display: inline-flex;
align-items: center;

View file

@ -35,11 +35,6 @@
}
}
:global(.portfolio p) {
margin: 1rem 0;
padding: 0;
}
:global(.portfolio-details) {
margin: 0 1.5rem;

View file

@ -1,4 +1,8 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { Pagination } from "bits-ui";
import { ChevronLeft, ChevronRight } from 'lucide-svelte';
export let additionalClasses: string;
export let pageSize: number;
export let totalCount: number;
@ -11,47 +15,80 @@
$: nextPage = currentPage + 1;
$: hasNextPage = nextPage <= totalPages;
$: hasPrevPage = prevPage >= 1;
$: console.log(hasPrevPage, hasNextPage, prevPage, nextPage, currentPage, totalPages, pageSize);
</script>
<div class={`paginationStyles ${additionalClasses}`}>
<a
title={`${!hasPrevPage ? 'No ' : ''}Prev Page`}
aria-disabled={!hasPrevPage}
href={`${base}/${prevPage}`}
>
&#8592; <span class="word">Prev</span>
</a>
{#each { length: totalPages } as _, i}
<a
aria-current={currentPage === i + 1}
href={`${base}/${i + 1}`}
>
{i + 1}
</a>
<Pagination.Root let:pages count={totalCount} perPage={pageSize} page={currentPage || 1} class={`${additionalClasses}`}
onPageChange={(page) => goto(`${base}/${page}`)}>
<Pagination.PrevButton>
<ChevronLeft />
</Pagination.PrevButton>
{#each pages as page (page.key)}
{#if page.type === "ellipsis"}
<div class="text-[15px] font-medium text-foreground-alt">...</div>
{:else}
<Pagination.Page {page}>
<a href={`${base}/${page.value}`}>
{page.value}
</a>
</Pagination.Page>
{/if}
{/each}
<a
title={`${!hasNextPage ? 'No ' : ''}Next Page`}
aria-disabled={!hasNextPage}
href={`${base}/${nextPage}`}
>
<span class="word">Next</span> &#8594;
</a>
</div>
<Pagination.NextButton>
<ChevronRight />
</Pagination.NextButton>
</Pagination.Root>
<style lang="postcss">
a {
&[aria-current="true"] {
color: var(--shellYellow)
:global([data-pagination-prev-button]) {
&:hover {
color: var(--shellYellow);
}
&[aria-disabled="true"] {
pointer-events: none;
color: var(--lightGrey);
text-decoration: line-through;
&:active {
transform: scale(0.98); /* Equivalent to active:scale-98 in Tailwind */
}
&:disabled {
cursor: not-allowed; /* Equivalent to disabled:cursor-not-allowed in Tailwind */
color: #6b7280; /* Equivalent to disabled:text-muted-foreground in Tailwind */
}
&:hover:disabled {
background-color: transparent; /* Equivalent to hover:disabled:bg-transparent in Tailwind */
}
border-right: 1px solid var(--grey);
padding: 1rem;
}
:global([data-pagination-next-button]) {
&:hover {
color: var(--shellYellow);
}
&:active {
transform: scale(0.98); /* Equivalent to active:scale-98 in Tailwind */
}
&:disabled {
cursor: not-allowed; /* Equivalent to disabled:cursor-not-allowed in Tailwind */
color: #6b7280; /* Equivalent to disabled:text-muted-foreground in Tailwind */
}
&:hover:disabled {
background-color: transparent; /* Equivalent to hover:disabled:bg-transparent in Tailwind */
}
}
.paginationStyles {
:global([data-selected]) {
a {
color: var(--shellYellow);
}
}
:global([data-pagination-root]) {
display: flex;
align-content: center;
align-items: center;
@ -61,17 +98,16 @@
border-radius: 5px;
text-align: center;
font-size: 1.5rem;
& > * {
padding: 1rem;
flex: 1;
border-right: 1px solid var(--grey);
text-decoration: none;
}
@media (max-width: 800px) {
.word {
display: none;
}
}
}
:global([data-pagination-page]) {
padding: 1rem;
flex: 1;
border-right: 1px solid var(--grey);
text-decoration: none;
a {
text-decoration: none;
}
}
</style>

View file

@ -1,6 +1,6 @@
import { json, error } from '@sveltejs/kit';
import { WALLABAG_MAX_PAGES } from '$env/static/private';
import { fetchArticlesApi } from '$root/routes/api';
import { fetchArticlesApi } from '$lib/api';
export async function GET({ setHeaders, url }) {
const page = url?.searchParams?.get('page') || '1';

View file

@ -1,16 +1,16 @@
import { error } from '@sveltejs/kit';
import type { MetaTagsProps } from 'svelte-meta-tags';
import type { PageServerLoad } from './$types';
import { WALLABAG_MAX_PAGES } from '$env/static/private';
import { PUBLIC_SITE_URL } from '$env/static/public';
import type { ArticlePageLoad } from '$lib/types/article';
import type { MetaTagsProps } from 'svelte-meta-tags';
export const load: PageServerLoad = async ({ fetch, params, setHeaders, url }) => {
const { page } = params;
if (+page > +WALLABAG_MAX_PAGES) {
error(404, {
message: 'Not found'
});
message: 'Not found',
});
}
const resp = await fetch(`/api/articles?page=${page}`);
const { articles, currentPage, totalPages, limit, totalArticles, cacheControl }: ArticlePageLoad =
@ -18,11 +18,11 @@ export const load: PageServerLoad = async ({ fetch, params, setHeaders, url }) =
if (cacheControl?.includes('no-cache')) {
setHeaders({
'cache-control': cacheControl
'cache-control': cacheControl,
});
} else {
setHeaders({
'cache-control': 'max-age=43200' // 12 hours
'cache-control': 'max-age=43200', // 12 hours
});
}
@ -33,7 +33,7 @@ export const load: PageServerLoad = async ({ fetch, params, setHeaders, url }) =
title: 'Favorite Articles',
description: 'My favorite articles',
openGraph: {
title: 'Facorite Articles',
title: 'Favorite Articles',
description: 'My favorite articles',
url: currentPageUrl,
siteName: 'Bradley Shellnut Personal Website',
@ -44,18 +44,18 @@ export const load: PageServerLoad = async ({ fetch, params, setHeaders, url }) =
url: `${baseUrl}og?header=Articles Page ${page} | bradleyshellnut.com&page=My favorite articles`,
alt: `Bradley Shellnut Articles Page ${page}`,
width: 1200,
height: 630
}
]
height: 630,
},
],
},
twitter: {
title: 'Favorite Articles',
description: 'My favorite articles',
card: 'summary_large_image',
image: `${baseUrl}og?header=Articles Page ${page} | bradleyshellnut.com&page=My favorite articles`,
imageAlt: 'Bradley Shellnut Website Logo'
imageAlt: 'Bradley Shellnut Website Logo',
},
url: currentPageUrl
url: currentPageUrl,
});
return {
@ -64,6 +64,6 @@ export const load: PageServerLoad = async ({ fetch, params, setHeaders, url }) =
totalPages,
limit,
totalArticles,
metaTagsChild: metaTags
metaTagsChild: metaTags,
};
};

View file

@ -1,8 +1,8 @@
<script lang="ts">
import Pagination from "$lib/components/pagination/index.svelte";
import type { Article } from "$lib/types/article";
import Articles from "$lib/components/Articles.svelte";
import type { PageData } from "./$types";
import Pagination from '$lib/components/pagination/index.svelte';
import type { Article } from '$lib/types/article';
import Articles from '$lib/components/Articles.svelte';
import type { PageData } from './$types';
export let data: PageData;
let articles: Article[];
@ -10,11 +10,13 @@
let totalArticles: number;
let limit: number;
$: ({ articles, currentPage, totalPages, totalArticles, limit } = data);
$: console.log(currentPage, totalPages, totalArticles, limit);
</script>
<div>
<h1 style="margin-bottom: 2rem">Favorite Tech Articles</h1>
<Pagination
<Pagination
additionalClasses="top-pagination"
pageSize={limit}
totalCount={totalArticles}

View file

@ -44,9 +44,7 @@
loading="eager"
alt="Picture of Bradley Shellnut's Personal Website">
<span slot="portfolio-links">
<p>
<ExternalLink ariaLabel="View GitHub repository for my personal website" href="https://github.com/BradNut/personal-website-sveltekit" icon={GitHub} showIcon>GitHub repository</ExternalLink>
</p>
<ExternalLink ariaLabel="View GitHub repository for my personal website" href="https://github.com/BradNut/personal-website-sveltekit" icon={GitHub} showIcon>GitHub repository</ExternalLink>
</span>
<PersonalWebsiteSvelteKit slot="portfolio-details" />
</Portfolio>
@ -55,12 +53,8 @@
src={weddingWebsite}
alt="Picture of NextJS Wedding Website">
<span slot="portfolio-links">
<p>
<ExternalLink ariaLabel="View Wedding Website" href="https://weddingsite-six.vercel.app/" showIcon>View Site</ExternalLink>
</p>
<p>
<ExternalLink ariaLabel="View GitHub repository for the wedding site" href="https://github.com/BradNut/weddingsite" icon={GitHub} showIcon>GitHub repository</ExternalLink>
</p>
<ExternalLink ariaLabel="View Wedding Website" href="https://weddingsite-six.vercel.app/" showIcon>View Site</ExternalLink>
<ExternalLink ariaLabel="View GitHub repository for the wedding site" href="https://github.com/BradNut/weddingsite" icon={GitHub} showIcon>GitHub repository</ExternalLink>
</span>
<WeddingWebsite slot="portfolio-details" />
</Portfolio>
@ -69,9 +63,7 @@
src={oldSite}
alt="Home Page of the old bradleyshellnut.com website">
<span slot="portfolio-links">
<p>
<ExternalLink ariaLabel="Archive of bradleyshellnut.com" href="https://web.archive.org/web/20201205233507/https://bradleyshellnut.com/about" showIcon>Link to an archive snapshot</ExternalLink>
</p>
<ExternalLink ariaLabel="Archive of bradleyshellnut.com" href="https://web.archive.org/web/20201205233507/https://bradleyshellnut.com/about" showIcon>Link to an archive snapshot</ExternalLink>
</span>
<OldWebsite slot="portfolio-details" />
</Portfolio>
@ -82,9 +74,7 @@
src={shellnutArchitectWebsite}
alt="Picture of Mark Shellnut Architect's Website">
<span slot="portfolio-links">
<p>
<ExternalLink ariaLabel="View markshellnutarchitect.com" href="https://markshellnutarchitect.com" showIcon>Link to Mark Shellnut's Website</ExternalLink>
</p>
<ExternalLink ariaLabel="View markshellnutarchitect.com" href="https://markshellnutarchitect.com" showIcon>Link to Mark Shellnut's Website</ExternalLink>
</span>
<MarkShellnutArchitect slot="portfolio-details" />
</Portfolio>

7
src/state/search.ts Normal file
View file

@ -0,0 +1,7 @@
import { persisted } from 'svelte-local-storage-store';
import { writable } from 'svelte/store';
export const searching = writable(false);
export const overlay_open = writable(false);
export const search_query = writable('');
export const search_recent = persisted<string[]>('svelte:recent-searches', []);

View file

@ -24,6 +24,9 @@ const config = {
alias: {
$root: './src'
}
},
compilerOptions: {
enableSourcemap: process.env.NODE_ENV === 'development',
}
};

View file

@ -5,6 +5,7 @@
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"useUnknownInCatchVariables": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,