Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS

Introduction

As a developer always eager to learn and showcase my work, I wanted a “portfolio” application to share my learnings and projects. While searching for inspiration, I stumbled upon Spotlight by TailwindUI and [briandev’s spotlight…


This content originally appeared on DEV Community and was authored by John Owolabi Idogun

Introduction

As a developer always eager to learn and showcase my work, I wanted a "portfolio" application to share my learnings and projects. While searching for inspiration, I stumbled upon Spotlight by TailwindUI and [briandev's spotlight],2 a stunning UI created by the Tailwind CSS team. However, since it is a paid product and built with Next.js, I decided to challenge myself by replicating it using SvelteKit, specifically to explore the new features of Svelte 5, which was a release candidate at the time.

My goal was to recreate the spotlight design while integrating additional functionalities such as syntax highlighting with Highlight.js, a dev.to-like new post creation page, a commenting system, and the ability to modify and run some code blocks directly within the application.

Source Code

You can access the complete source code for this project on GitHub:

GitHub logo Sirneij / spotlight-sveltekit

Svelte 5 version of tailwindcss spotlight ui

create-svelte

Everything you need to build a Svelte project, powered by create-svelte.

Creating a project

If you're seeing this, you've probably already done this step. Congrats!

# create a new project in the current directory
npm create svelte@latest

# create a new project in my-app
npm create svelte@latest my-app

Developing

Once you've created a project and installed dependencies with npm install (or pnpm install or yarn), start a development server:

npm run dev

# or start the server and open the app in a new browser tab
npm run dev -- --open

Building

To create a production version of your app:

npm run build

You can preview the production build with npm run preview.

To deploy your app, you may need to install an adapter for your target environment.




Additionally, the application is live at spotlight-sveltekit.vercel.app.

Implementation

Step 1: Setting Up the Project and Layout

Installing TailwindCSS

First, we need to set up TailwindCSS in our SvelteKit project. Follow the official TailwindCSS installation guide for SvelteKit to get started. Once TailwindCSS is installed, we can proceed to configure our layout.

Modifying app.html and Creating +layout.svelte

In app.html, ensure you include some of the theme-switching scripts which allow us to persist the user's desired theme in the browser's localStorage. See src/app.html.

Next, we create +layout.svelte to define our main layout structure:

<script lang="ts">
  import Footer from "$lib/components/layout/Footer.svelte";
  import Header from "$lib/components/layout/Header.svelte";
  import type { Snippet } from "svelte";
  import "../app.css";
  import type { PageData } from "./$types";

  const { data, children }: { data: PageData; children: Snippet } = $props();
  const isCreate = $derived(data.url.includes("create"));
</script>

<div class="fixed inset-0 flex justify-center sm:px-8">
  <div class="flex w-full max-w-7xl lg:px-8">
    <div
      class="w-full bg-white ring-1 ring-zinc-100 dark:bg-zinc-900 dark:ring-zinc-300/20"
    ></div>
  </div>
</div>
<div class="relative" class:h-screen="{isCreate}">
  <Header isHomePage={data.url === '/'} {isCreate} />
  <main>{@render children()}</main>
  {#if !isCreate}
  <footer />
  {/if}
</div>

In Svelte 5, $props replaces export let from Svelte 4. Hence, instead of export let data: PageData, I did:

<script lang="ts">
  ...
  const { data, children }: { data: PageData; children: Snippet } = $props();
  ...
</script>

$props() also have a reserved property, called children, which contains default content. There's a new feature called Snippet.

The $effect rune is used in place of onMount and onDestroy. Learn more about these new runes and other stuff on the Svelte 5 documentation. Also, note how {@render children()} replaces <slot/>. You don't need Svelte stores in Svelte 5. You can have a .svelte.ts file that exposes some variables which use the svelte rune. For instance, in the dev.to-like editor I built, I store tags using this class:

/**
 * Represents the state of tags.
 *
 * @class TagState
 * @property {Set<string>} tagList - Set of tags.
 * @method addTag - Add a tag to the set.
 * @example
 * ```

javascript
 * import { tagState } from '$lib/states/tags.svelte';
 *
 * tagState.addTag('tag');
 *

  • @file frontend/src/lib/states/tags.svelte.ts */ class TagState { // Set of tags. tagList = $state>(new Set());

// Add a tag to the set.
addTag(tag: string) {
this.tagList.add(tag);
}
}

export const tagState = new TagState();

export const tagsAbortController = new AbortController();




It serves as my store!!! Beautiful, huh?

### Step 2: Integrating Highlight.js

For syntax highlighting, I used Highlight.js. I created a custom wrapper to handle code block rendering and highlighting. Take a look at [src/lib/utils/helpers/code.block.ts][7].

This wrapper supports theme switching between `horizon-dark` and `night-owl`, displays filenames, allows code copying, and even runs some code using an `iframe` for security reasons. The design of the code block component is inspired by TailwindCSS's own documentation style.

### Step 3: Creating a dev.to-like Custom Editor

#### Tag Selection with Suggestions

For the tag selection feature, I used a combination of Svelte's reactivity and some functions to provide suggestions as users type. The code works but it can be cleaned further.

#### Markdown Rich-Text Editor

For the markdown editor, I built a user-friendly markdown editor interface. It has most of dev.to's features including keyboard combinations. It detects the Operating system a user is running and gives key combinations based on this. You can combine three keys together. For instance, `CMD/CTRL + SHIFT + K` will add this command to the textarea:



```language:filename {line nos} runnable:
<code here>

language is the programming language. filename is the name of the file you want to display its code. {line nos} represents the line numbers, separated by commas, you want to emphasize. runnable denotes whether or not the code can be run. If it's present, it means it can be run. Otherwise, it can't. This custom code block is parsed by a custom parser to extract these parts using regex.

Custom Parser for GitHub Repos

I wrote a custom parser to detect and embed GitHub repositories as well. Just like dev.to's.

The full implementation includes other features and refinements, which you can explore in the source code.

Future Enhancements

The final version of this application for my portfolio will include a backend built with either Go or Rust, incorporating more robust features such as a real-time commenting system. Stay tuned for updates, and feel free to suggest new features or your preferred backend language.

Outro

Enjoyed this article? I'm a Software Engineer and Technical Writer actively seeking new opportunities, particularly in areas related to web security, finance, healthcare, and education. If you think my expertise aligns with your team's needs, let's chat! You can find me on LinkedIn and Twitter.

If you found this article valuable, consider sharing it with your network to help spread the knowledge!


This content originally appeared on DEV Community and was authored by John Owolabi Idogun


Print Share Comment Cite Upload Translate Updates
APA

John Owolabi Idogun | Sciencx (2024-06-30T01:59:55+00:00) Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS. Retrieved from https://www.scien.cx/2024/06/30/building-tailwinduis-spotlight-using-sveltekit-and-svelte-5-with-tailwindcss/

MLA
" » Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS." John Owolabi Idogun | Sciencx - Sunday June 30, 2024, https://www.scien.cx/2024/06/30/building-tailwinduis-spotlight-using-sveltekit-and-svelte-5-with-tailwindcss/
HARVARD
John Owolabi Idogun | Sciencx Sunday June 30, 2024 » Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS., viewed ,<https://www.scien.cx/2024/06/30/building-tailwinduis-spotlight-using-sveltekit-and-svelte-5-with-tailwindcss/>
VANCOUVER
John Owolabi Idogun | Sciencx - » Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/30/building-tailwinduis-spotlight-using-sveltekit-and-svelte-5-with-tailwindcss/
CHICAGO
" » Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS." John Owolabi Idogun | Sciencx - Accessed . https://www.scien.cx/2024/06/30/building-tailwinduis-spotlight-using-sveltekit-and-svelte-5-with-tailwindcss/
IEEE
" » Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS." John Owolabi Idogun | Sciencx [Online]. Available: https://www.scien.cx/2024/06/30/building-tailwinduis-spotlight-using-sveltekit-and-svelte-5-with-tailwindcss/. [Accessed: ]
rf:citation
» Building TailwindUI’s Spotlight using SvelteKit and Svelte 5 with TailwindCSS | John Owolabi Idogun | Sciencx | https://www.scien.cx/2024/06/30/building-tailwinduis-spotlight-using-sveltekit-and-svelte-5-with-tailwindcss/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.