feat: Add Image and Link components
This commit is contained in:
parent
67140bb47e
commit
da5b2a1c23
3
app/bun.lock
Executable file → Normal file
3
app/bun.lock
Executable file → Normal file
@ -7,6 +7,7 @@
|
|||||||
"@fastify/static": "^8.1.1",
|
"@fastify/static": "^8.1.1",
|
||||||
"@universal-middleware/core": "^0.4.7",
|
"@universal-middleware/core": "^0.4.7",
|
||||||
"@universal-middleware/fastify": "^0.5.16",
|
"@universal-middleware/fastify": "^0.5.16",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
"fastify": "^5.3.0",
|
"fastify": "^5.3.0",
|
||||||
"solid-js": "^1.9.5",
|
"solid-js": "^1.9.5",
|
||||||
"telefunc": "^0.2.3",
|
"telefunc": "^0.2.3",
|
||||||
@ -369,6 +370,8 @@
|
|||||||
|
|
||||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
|
|
||||||
|
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||||
|
|
||||||
"code-block-writer": ["code-block-writer@12.0.0", "", {}, "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w=="],
|
"code-block-writer": ["code-block-writer@12.0.0", "", {}, "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w=="],
|
||||||
|
|
||||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||||
|
|||||||
18
app/components/Image.tsx
Normal file
18
app/components/Image.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import type { JSX } from "solid-js";
|
||||||
|
|
||||||
|
type ImageProps = JSX.IntrinsicElements["img"] & { src: string; alt: string };
|
||||||
|
|
||||||
|
export function Image(props: ImageProps) {
|
||||||
|
const isDecorationImage = props.alt === "";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
{...props}
|
||||||
|
src={props.src}
|
||||||
|
role={isDecorationImage ? "presentation" : "img"}
|
||||||
|
aria-hidden={isDecorationImage ? "true" : undefined}
|
||||||
|
alt={isDecorationImage ? undefined : props.alt}
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,14 +1,35 @@
|
|||||||
import { createMemo } from "solid-js";
|
import type { JSX } from "solid-js";
|
||||||
|
|
||||||
import { usePageContext } from "vike-solid/usePageContext";
|
import { usePageContext } from "vike-solid/usePageContext";
|
||||||
|
|
||||||
export function Link(props: { href: string; children: string }) {
|
type LinkProps = JSX.IntrinsicElements["a"] & { href: string };
|
||||||
const pageContext = usePageContext();
|
|
||||||
const isActive = createMemo(() =>
|
export function Link(props: LinkProps) {
|
||||||
props.href === "/" ? pageContext.urlPathname === props.href : pageContext.urlPathname.startsWith(props.href),
|
const { urlPathname } = usePageContext();
|
||||||
);
|
|
||||||
return (
|
const isActive =
|
||||||
<a href={props.href} class={isActive() ? "is-active" : undefined}>
|
props.href === "/"
|
||||||
{props.children}
|
? urlPathname === props.href
|
||||||
</a>
|
: urlPathname.startsWith(props.href);
|
||||||
);
|
|
||||||
|
const isSameDomain = !(
|
||||||
|
props.href.startsWith("http") || props.href.startsWith("mailto")
|
||||||
|
);
|
||||||
|
|
||||||
|
const downloadExtensions = [".pdf", ".zip"];
|
||||||
|
|
||||||
|
const isDownload = downloadExtensions.some(props.href.endsWith);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
{...props}
|
||||||
|
{...(isActive && { ariaCurrent: "page" })}
|
||||||
|
{...(isDownload && { download: true })}
|
||||||
|
{...(!isSameDomain || isDownload
|
||||||
|
? { target: "_blank", rel: "noopener noreferrer" }
|
||||||
|
: { target: "_self" })}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,15 +8,16 @@
|
|||||||
"format": "biome format --write ."
|
"format": "biome format --write ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vike": "^0.4.228",
|
|
||||||
"@fastify/middie": "^9.0.3",
|
"@fastify/middie": "^9.0.3",
|
||||||
"@fastify/static": "^8.1.1",
|
"@fastify/static": "^8.1.1",
|
||||||
"@universal-middleware/fastify": "^0.5.16",
|
|
||||||
"fastify": "^5.3.0",
|
|
||||||
"@universal-middleware/core": "^0.4.7",
|
"@universal-middleware/core": "^0.4.7",
|
||||||
|
"@universal-middleware/fastify": "^0.5.16",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"fastify": "^5.3.0",
|
||||||
"solid-js": "^1.9.5",
|
"solid-js": "^1.9.5",
|
||||||
"vike-solid": "^0.7.9",
|
"telefunc": "^0.2.3",
|
||||||
"telefunc": "^0.2.3"
|
"vike": "^0.4.228",
|
||||||
|
"vike-solid": "^0.7.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "1.9.4",
|
||||||
|
|||||||
@ -1,28 +1,23 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"moduleResolution": "Bundler",
|
"moduleResolution": "Bundler",
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"lib": [
|
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||||
"DOM",
|
"types": ["vite/client", "vike-solid/client"],
|
||||||
"DOM.Iterable",
|
"jsx": "react-jsx",
|
||||||
"ESNext"
|
"jsxImportSource": "solid-js",
|
||||||
],
|
"baseUrl": ".",
|
||||||
"types": [
|
"paths": {
|
||||||
"vite/client",
|
"@/*": ["./*"]
|
||||||
"vike-solid/client"
|
}
|
||||||
],
|
},
|
||||||
"jsx": "react-jsx",
|
"exclude": ["dist"]
|
||||||
"jsxImportSource": "solid-js"
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"dist"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
@ -1,12 +1,20 @@
|
|||||||
import { telefunc } from "telefunc/vite";
|
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
|
import { telefunc } from "telefunc/vite";
|
||||||
import vikeSolid from "vike-solid/vite";
|
import vikeSolid from "vike-solid/vite";
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import vike from "vike/plugin";
|
import vike from "vike/plugin";
|
||||||
|
import path from "node:path";
|
||||||
|
|
||||||
|
const __dirname = path.resolve();
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [vike(), vikeSolid(), tailwindcss(), telefunc()],
|
plugins: [vike(), vikeSolid(), tailwindcss(), telefunc()],
|
||||||
build: {
|
build: {
|
||||||
target: "es2022",
|
target: "es2022",
|
||||||
},
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": __dirname,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user