DEV Community

Zied Hamdi
Zied Hamdi

Posted on • Edited on

How I integrated preline to work in SvelteKit

Image description

As I'm leaving medium to come here, this is my first article on dev.to. I hope you'll like it.

I decided to launch a resume builder with Sveltkit at CvLink.

After testing Flowbite, I had a clear preference for the look and feel and component offer of Preline.

But it was not easy to have the components react to click events. So I'm sharing what I did because I couldn't find any info on the web.

Steps

I'm presenting the steps briefly as I suppose that's what you're waiting for: getting it done and walk away :-)

install Preline

pnpm add preline

Add TailwindCss

to do the equivalent of npx in pnpm:
npx svelte-add@latest tailwindcss
pnpm i

Install svelte-add globally, then use it to add tailwindcss
pnpm install -g svelte-add
svelte-add tailwindcss

Configure tailwind

tailwind.config.js

const config = { content: [ "./src/**/*.{html,js,svelte,ts}", "./node_modules/preline/dist/*.js", ], theme: { extend: {}, }, plugins: [ require('preline/plugin') ], darkMode: 'class', }; module.exports = config; 
Enter fullscreen mode Exit fullscreen mode

Adapt Preline js files

Instead of having the js load at document.on('load') ex:

document.addEventListener('load', window.HSAccordion.init()); 
Enter fullscreen mode Exit fullscreen mode

We make it load lazily when a component displays for its first time.

Files were copied from preline

I copied ./core/component.js to a local folder ./preline/component

And copied HSAccordion to ./accordion/Accordion.js next to its Svelte component

Skipping js-loading when in SSR

Accordion

When index.js was loaded, it attached components' js to window like follows:

window.HSAccordion = new HSAccordion(); document.addEventListener('load', window.HSAccordion.init()); 
Enter fullscreen mode Exit fullscreen mode

I moved that init code to the AccordionItem component, checking i'm in the browser before initializing like follows:

<script> import Accordion from './Accordion'; if(typeof window !== 'undefined') { console.log( "initializing accordion" ) window.HSAccordion = new Accordion(); window.HSAccordion.init(); } export let name; </script> 
Enter fullscreen mode Exit fullscreen mode

The code for the accordion is pretty direct, then:
AccordionItem.svelte

<script> import Accordion from './Accordion'; if(typeof window !== 'undefined') { console.log( "initializing accordion" ) window.HSAccordion = new Accordion(); window.HSAccordion.init(); } export let name; </script> <li class='hs-accordion' id='account-accordion'> <a class='hs-accordion-toggle flex items-center gap-x-3.5 py-2 px-2.5 hs-accordion-active:text-blue-600 hs-accordion-active:hover:bg-transparent text-sm text-slate-700 rounded-md hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-slate-400 dark:hover:text-slate-300 dark:hs-accordion-active:text-white' href='javascript:;'> <slot name='icon' /> <slot name='name'>{name}</slot> <svg class='hs-accordion-active:block ml-auto hidden w-3 h-3 text-gray-600 group-hover:text-gray-500 dark:text-gray-400' width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'> <path d='M2 11L8.16086 5.31305C8.35239 5.13625 8.64761 5.13625 8.83914 5.31305L15 11' stroke='currentColor' stroke-width='2' stroke-linecap='round'></path> </svg> <svg class='hs-accordion-active:hidden ml-auto block w-3 h-3 text-gray-600 group-hover:text-gray-500 dark:text-gray-400' width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'> <path d='M2 5L8.16086 10.6869C8.35239 10.8637 8.64761 10.8637 8.83914 10.6869L15 5' stroke='currentColor' stroke-width='2' stroke-linecap='round'></path> </svg> </a> <div id='account-accordion-child' class='hs-accordion-content w-full overflow-hidden transition-[height] duration-300 hidden'> <slot name='content' /> </div> </li> 
Enter fullscreen mode Exit fullscreen mode

I created a repository where you can benefit of the work directly.

Known bugs: Sometimes the js is not loaded, happens in dev mode, I still didn't check if it happens in prod.

Top comments (0)