105 lines
3.3 KiB
Text
105 lines
3.3 KiB
Text
|
|
<button
|
||
|
|
type="button"
|
||
|
|
class="focus-visible:ring-secondary group inline-flex items-center rounded-lg p-2.5 text-neutral-600 outline-none ring-zinc-500 transition duration-300 hover:bg-neutral-100 focus:outline-none focus-visible:outline-none focus-visible:ring-1 dark:text-neutral-400 dark:ring-zinc-200 dark:hover:bg-neutral-700"
|
||
|
|
data-bookmark-button="bookmark-button"
|
||
|
|
>
|
||
|
|
<svg
|
||
|
|
fill="none"
|
||
|
|
viewBox="0 0 24 24"
|
||
|
|
stroke-width="1.5"
|
||
|
|
stroke="currentColor"
|
||
|
|
class="h-6 w-6 fill-none transition duration-300"
|
||
|
|
>
|
||
|
|
<path
|
||
|
|
stroke-linecap="round"
|
||
|
|
stroke-linejoin="round"
|
||
|
|
class="fill-current text-neutral-500 transition duration-300 group-hover:text-red-400 group-hover:dark:text-red-400"
|
||
|
|
d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"
|
||
|
|
></path>
|
||
|
|
</svg>
|
||
|
|
</button>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
class Bookmark {
|
||
|
|
private static readonly BOOKMARKS_KEY = "bookmarks";
|
||
|
|
private bookmarkButton: Element | null;
|
||
|
|
|
||
|
|
constructor(private dataAttrValue: string) {
|
||
|
|
this.bookmarkButton = document.querySelector(
|
||
|
|
`[data-bookmark-button="${dataAttrValue}"]`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
private getStoredBookmarks(): string[] {
|
||
|
|
const item = localStorage.getItem(Bookmark.BOOKMARKS_KEY);
|
||
|
|
return item ? JSON.parse(item) : [];
|
||
|
|
}
|
||
|
|
|
||
|
|
init(): void {
|
||
|
|
if (this.bookmarkButton && this.isStored()) {
|
||
|
|
this.markAsStored();
|
||
|
|
}
|
||
|
|
|
||
|
|
this.bookmarkButton?.addEventListener("click", () =>
|
||
|
|
this.toggleBookmark()
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
isStored(): boolean {
|
||
|
|
return this.getStoredBookmarks().includes(window.location.pathname);
|
||
|
|
}
|
||
|
|
markAsStored(): void {
|
||
|
|
if (this.bookmarkButton) {
|
||
|
|
this.bookmarkButton.classList.add("bookmarked");
|
||
|
|
let svgElement = this.bookmarkButton.querySelector("svg");
|
||
|
|
if (svgElement) {
|
||
|
|
svgElement.setAttribute(
|
||
|
|
"class",
|
||
|
|
"h-6 w-6 fill-red-500 dark:fill-red-500"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
let pathElement = svgElement?.querySelector("path");
|
||
|
|
if (pathElement) {
|
||
|
|
pathElement.setAttribute(
|
||
|
|
"class",
|
||
|
|
"fill-current text-red-500 dark:text-red-500"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
unmarkAsStored(): void {
|
||
|
|
if (this.bookmarkButton) {
|
||
|
|
this.bookmarkButton.classList.remove("bookmarked");
|
||
|
|
let svgElement = this.bookmarkButton.querySelector("svg");
|
||
|
|
if (svgElement) {
|
||
|
|
svgElement.setAttribute("class", "h-6 w-6 fill-none");
|
||
|
|
}
|
||
|
|
let pathElement = svgElement?.querySelector("path");
|
||
|
|
if (pathElement) {
|
||
|
|
pathElement.setAttribute(
|
||
|
|
"class",
|
||
|
|
"fill-current text-neutral-500 group-hover:text-red-400 dark:text-neutral-500 group-hover:dark:text-red-400"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
toggleBookmark(): void {
|
||
|
|
let storedBookmarks = this.getStoredBookmarks();
|
||
|
|
const index = storedBookmarks.indexOf(window.location.pathname);
|
||
|
|
if (index !== -1) {
|
||
|
|
storedBookmarks.splice(index, 1);
|
||
|
|
this.unmarkAsStored();
|
||
|
|
} else {
|
||
|
|
storedBookmarks.push(window.location.pathname);
|
||
|
|
this.markAsStored();
|
||
|
|
}
|
||
|
|
localStorage.setItem(
|
||
|
|
Bookmark.BOOKMARKS_KEY,
|
||
|
|
JSON.stringify(storedBookmarks)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
new Bookmark("bookmark-button").init();
|
||
|
|
</script>
|