86 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ---
 | |
| import Icon from '@components/ui/icons/icon.astro';
 | |
| ---
 | |
| 
 | |
| <button
 | |
|   type="button"
 | |
|   class="focus-visible:ring-secondary group inline-flex items-center rounded-lg p-2.5 text-neutral-600 ring-neutral-500 transition duration-300 outline-none hover:bg-neutral-100 focus:outline-none focus-visible:ring-1 focus-visible:outline-none dark:text-neutral-400 dark:ring-neutral-200 dark:hover:bg-neutral-700"
 | |
|   data-bookmark-button="bookmark-button"
 | |
| >
 | |
|   <Icon name="bookmark" />
 | |
| </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');
 | |
|         const svgElement = this.bookmarkButton.querySelector('svg');
 | |
|         if (svgElement) {
 | |
|           svgElement.setAttribute('class', 'h-6 w-6 fill-red-500 dark:fill-red-500');
 | |
|         }
 | |
|         const 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');
 | |
|         const svgElement = this.bookmarkButton.querySelector('svg');
 | |
|         if (svgElement) {
 | |
|           svgElement.setAttribute('class', 'h-6 w-6 fill-none');
 | |
|         }
 | |
|         const 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 {
 | |
|       const 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>
 |