diff --git a/resources/ts/image-block-helper.ts b/resources/ts/image-block-helper.ts new file mode 100644 index 00000000..397f2306 --- /dev/null +++ b/resources/ts/image-block-helper.ts @@ -0,0 +1,98 @@ +import { Modal } from './modal.js'; + +declare global { + interface Window { + imageBlockHelper: (element: HTMLElement) => void; + } +} + +const BASE_BUTTON_CLASS_NAME: string[] = [ + 'absolute', + 'size-8', + 'flex', + 'justify-center', + 'items-center', + 'text-gray-50', + 'bg-emerald-500', + 'dark:bg-lividus-500', + 'rounded-md', + 'text-lg', + 'hover:bg-emerald-600', + 'dark:hover:bg-lividus-400', + 'active:bg-emerald-500', + 'dark:active:bg-lividus-500', + 'opacity-0', + 'group-hover:opacity-100', + 'transition-all', + 'duration-200', +]; + +const ARROWS_ANGLE_EXPAND_ICON_SVG: string = ` + + + +`; + +function createExpandImageButton(preOuterHtml: string): HTMLButtonElement { + const expandImageButton: HTMLButtonElement = + document.createElement('button'); + expandImageButton.classList.add( + 'top-2', + 'right-2', + ...BASE_BUTTON_CLASS_NAME, + ); + expandImageButton.innerHTML = ARROWS_ANGLE_EXPAND_ICON_SVG; + + const modal = new Modal({ + innerHtml: preOuterHtml, + customClassName: ['font-jetbrains-mono', 'text-xl'], + }); + + expandImageButton.addEventListener( + 'click', + function (this: HTMLButtonElement) { + modal.open(); + }, + ); + + return expandImageButton; +} + +window.imageBlockHelper = function (element: HTMLElement): void { + const figureTags: HTMLCollectionOf = + element.getElementsByTagName('figure'); + + for (const figureTag of figureTags) { + if (figureTag.classList.contains('image-block-helper-added')) { + return; + } + + figureTag.classList.add( + 'image-block-helper-added', + 'group', + 'relative', + ); + + const image = figureTag.getElementsByTagName('img')[0]; + + image.removeAttribute('height'); + image.removeAttribute('width'); + + const expandImageButton = createExpandImageButton(image.outerHTML); + + figureTag.appendChild(expandImageButton); + + document.addEventListener( + 'livewire:navigating', + () => { + expandImageButton.remove(); + figureTag.classList.remove( + 'image-block-helper-added', + 'group', + 'relative', + ); + }, + { once: true }, + ); + } +}; diff --git a/resources/views/livewire/pages/posts/show-post-page.blade.php b/resources/views/livewire/pages/posts/show-post-page.blade.php index 6b6d61e9..37115cbc 100644 --- a/resources/views/livewire/pages/posts/show-post-page.blade.php +++ b/resources/views/livewire/pages/posts/show-post-page.blade.php @@ -17,6 +17,7 @@ @vite('resources/ts/highlight.ts') {{-- code block copy button --}} @vite('resources/ts/code-block-helper.ts') + @vite('resources/ts/image-block-helper.ts') {{-- post read pregress bar --}} @vite('resources/ts/progress-bar.ts') {{-- scroll --}} @@ -38,6 +39,7 @@ window.setupPostOutline(this.$refs.postOutline, this.$refs.postBody); window.hljs.highlightAll(); window.codeBlockHelper(this.$refs.postBody); + window.imageBlockHelper(this.$refs.postBody); window.processYoutubeOembeds(); window.processTwitterOembeds(this.$refs.postBody); window.setupProgressBar(this.$refs.postCard, this.$refs.progressBar); diff --git a/vite.config.js b/vite.config.js index a5226d01..a9f4d3fe 100644 --- a/vite.config.js +++ b/vite.config.js @@ -17,6 +17,7 @@ export default defineConfig({ 'resources/ts/progress-bar.ts', 'resources/ts/scroll-to-anchor.ts', 'resources/ts/post-outline.ts', + 'resources/ts/image-block-helper.ts', // css 'resources/css/app.css', 'node_modules/@yaireo/tagify/dist/tagify.css',