Skip to content

Commit a52b108

Browse files
committed
fix: Improved use-favicon hook flexibility + docs + added actual favicon for landing page.
1 parent e1b6631 commit a52b108

File tree

6 files changed

+97
-15
lines changed

6 files changed

+97
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Based on the [@mantine/hooks](https://github.com/mantinedev/mantine/tree/master/
6262
- [ ] use-document-visibility
6363
- [ ] use-event-listener
6464
- [ ] use-eye-dropper
65-
- [x] use-favicon
65+
- [x] use-favicon (improved, more flexible)
6666
- [ ] use-fetch
6767
- [ ] use-focus-return
6868
- [ ] use-focus-trap
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
```tsx
2+
// ----------
3+
// Mantine Implementation
4+
// ----------
5+
26
const [favicon, setFavicon] = createSignal('https://docs.solidjs.com/favicon.svg');
37
const setXFavicon = () => setFavicon('https://x.com/favicon.ico');
48
const setSolidFavicon = () => setFavicon('https://docs.solidjs.com/favicon.svg');
59

6-
useFavicon(favicon);
10+
useFavicon(favicon); // Will always run at the start.
711

812
return (
913
<button onClick={setXFavicon}>Use X Favicon</button>
1014
<button onClick={setSolidFavicon}>Use SolidJS Favicon</button>
1115
)
16+
17+
// ----------
18+
// Improved Bagon Implementation
19+
// ----------
20+
const [favicon, setFavicon] = useFavicon(); // Don't pass an initial accessor, choose to run when you need to.
21+
22+
const setXFavicon = () => setFavicon('https://x.com/favicon.ico');
23+
const setSolidFavicon = () => setFavicon('https://docs.solidjs.com/favicon.svg');
24+
25+
return (
26+
<button onClick={setXFavicon}>Use X Favicon</button>
27+
<button onClick={setSolidFavicon}>Use SolidJS Favicon</button>
28+
);
1229
```

dev/components/examples/use-favicon/use-favicon.example.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ import { createSignal } from 'solid-js';
66
import { useMDXComponents } from 'solid-jsx';
77

88
export function UseFaviconExample() {
9-
const [favicon, setFavicon] = createSignal('https://docs.solidjs.com/favicon.svg');
9+
const [touched, setTouched] = createSignal(false);
10+
11+
// OLD Implementation:
12+
// const [favicon, setFavicon] = createSignal('https://docs.solidjs.com/favicon.svg');
13+
14+
// IMPROVED Implementation:
15+
const [_favicon, setFavicon] = useFavicon();
16+
1017
const setXFavicon = () => setFavicon('https://x.com/favicon.ico');
1118
const setSolidFavicon = () => setFavicon('https://docs.solidjs.com/favicon.svg');
1219

13-
useFavicon(favicon);
14-
1520
// @ts-ignore
1621
const components: any = useMDXComponents();
1722

@@ -23,14 +28,20 @@ export function UseFaviconExample() {
2328
>
2429
<div class="flex h-full w-full flex-col items-center justify-center gap-3 rounded-md border p-3 py-10 text-center text-sm">
2530
<button
26-
onClick={() => setXFavicon()}
31+
onClick={() => {
32+
setTouched(true);
33+
setXFavicon();
34+
}}
2735
class="rounded-md border px-2 py-1.5 transition active:scale-95"
2836
>
2937
X favicon
3038
</button>
3139

3240
<button
33-
onClick={() => setSolidFavicon()}
41+
onClick={() => {
42+
setTouched(true);
43+
setSolidFavicon();
44+
}}
3445
class="rounded-md border px-2 py-1.5 transition active:scale-95"
3546
>
3647
Solid favicon

dev/pages/+Layout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import { FlowProps } from 'solid-js';
22

33
import { Head } from 'vike-solid/Head';
44

5-
import '../styles/app.css';
65
import { MarkdownContextProvider } from 'dev/components/markdown/markdown.context';
6+
import '../styles/app.css';
77

88
export default function Layout(props: FlowProps) {
99
return (
1010
<>
1111
<Head>
1212
<meta charset="utf-8" />
13+
<link rel="icon" href="/favicon.svg" />
1314
<meta
1415
name="description"
1516
content="A collection of zero-dependency hooks for SolidJS forked directly from Mantine Hooks, with some improvements."

dev/public/favicon.svg

Lines changed: 41 additions & 0 deletions
Loading

src/use-favicon/use-favicon.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ const MIME_TYPES: Record<string, string> = {
99

1010
/**
1111
* A hook that sets the favicon of the page based on the url (accessor) passed.
12+
*
13+
* This has an improvement over Mantine's API. Mantine's requires you to rely
14+
* on effects. This one has two ways to use:
15+
* 1. Use the setter returned by the hook (don't pass an url).
16+
* 2. Pass an accessor (it will use the effect based on the accessor).
1217
*/
13-
export function useFavicon(url: Accessor<string>) {
18+
export function useFavicon(url?: Accessor<string>) {
19+
const [currentFaviconUrl, setCurrentFaviconUrl] = createSignal<string | undefined>(url?.());
1420
const [linkRef, setLinkRef] = createSignal<HTMLLinkElement>();
1521

16-
createEffect(() => {
17-
if (!url()) {
18-
return;
19-
}
22+
function setFaviconInHTML(faviconUrl: string) {
23+
if (!faviconUrl) return;
2024

2125
if (!linkRef()) {
2226
const existingElements = document.querySelectorAll<HTMLLinkElement>('link[rel*="icon"]');
@@ -28,11 +32,19 @@ export function useFavicon(url: Accessor<string>) {
2832
document.querySelector('head')!.appendChild(element);
2933
}
3034

31-
const splittedUrl = url().split('.');
35+
const splittedUrl = faviconUrl.split('.');
3236
linkRef()?.setAttribute(
3337
'type',
3438
MIME_TYPES[splittedUrl?.[splittedUrl.length - 1]?.toLowerCase()!]!,
3539
);
36-
linkRef()?.setAttribute('href', url());
40+
linkRef()?.setAttribute('href', faviconUrl);
41+
setCurrentFaviconUrl(faviconUrl);
42+
}
43+
44+
createEffect(() => {
45+
if (!url) return;
46+
setFaviconInHTML(url());
3747
});
48+
49+
return [currentFaviconUrl, setFaviconInHTML] as const;
3850
}

0 commit comments

Comments
 (0)