agentsclimarketplace

Admin ui svelte

Skill lindoelio/my-agent-skills/admin-ui-svelte

A collection of reusable Agent Skills for AI-powered development tools.

Install
npx -y skills add lindoelio/my-agent-skills --skill admin-ui-svelte

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use this skill when building admin dashboards, control panels, or internal tools with Tailwind CSS v4, Skeleton UI, and Svelte 5. Triggers for layouts with sidebar navigation, data tables with pagination/sorting, forms with validation, authentication pages, and responsive admin interfaces — even if the user doesn't explicitly mention "admin" or "dashboard." Covers Skeleton components, Svelte 5 runes ($state, $derived), and Tailwind v4 patterns.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

11.8 KB, as published. Nobody here has run it

Admin UI with Tailwind v4 + Skeleton + Svelte 5

Build modern, responsive admin dashboards using Tailwind CSS v4, Skeleton UI components, and Svelte 5 with runes.

Gotchas

Svelte 5 Runes:

  • Use $state() for reactive variables, not let count = 0 with reactivity
  • Use $derived() for computed values, not $: reactive statements
  • Use $effect() for side effects, not onMount for most cases
  • Props use $props() function, not export let

Tailwind v4 Differences:

  • No tailwind.config.js needed — configuration via CSS @theme directive
  • Import: @import 'tailwindcss' not @tailwind base; @tailwind components; @tailwind utilities
  • Use @tailwindcss/vite plugin, not @tailwindcss/postcss

Skeleton UI:

  • Set data-theme="cerberus" on <html> element for theme activation
  • Color tokens are dual-mode: bg-surface-50-950 (light-dark), text-surface-950-50
  • Import Skeleton CSS after Tailwind: @import '@skeletonlabs/skeleton'
  • Skeleton v4 uses Zag.js for components — check imports from @skeletonlabs/skeleton-svelte

Common Mistakes:

  • Don't use class="btn btn-primary" — Skeleton uses class="btn variant-filled-primary"
  • Don't forget data-theme attribute — components won't render correctly without it
  • Don't mix Svelte 4 and 5 syntax in the same file

Quick Start

CDN Setup (for prototyping)

<!doctype html>
<html lang="en" data-theme="cerberus">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Admin Dashboard</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@skeletonlabs/skeleton@latest/themes/cerberus.css" />
  </head>
  <body class="bg-surface-50-950">
    <div class="container mx-auto p-4">
      <h1 class="text-3xl font-bold text-surface-950-50">Dashboard</h1>
    </div>
  </body>
</html>

Full Project Setup

See installation guide for complete Vite + Svelte 5 + Tailwind v4 + Skeleton setup.

Core Layout Pattern

Admin dashboards typically use a three-region layout: sidebar, header, main content.

<script>
  let sidebarOpen = $state(true);
</script>

<div class="grid min-h-screen grid-cols-[auto_1fr]">
  <aside class="bg-surface-100-900 w-64 border-r border-surface-200-800">
    <nav class="p-4">
      <a href="/" class="block p-2 hover:bg-surface-200-800 rounded">Dashboard</a>
      <a href="/users" class="block p-2 hover:bg-surface-200-800 rounded">Users</a>
      <a href="/settings" class="block p-2 hover:bg-surface-200-800 rounded">Settings</a>
    </nav>
  </aside>

  <div class="grid grid-rows-[auto_1fr]">
    <header class="bg-surface-50-950 border-b border-surface-200-800 p-4 sticky top-0 z-10">
      <button onclick={() => sidebarOpen = !sidebarOpen}>Menu</button>
    </header>

    <main class="p-6">
      <slot />
    </main>
  </div>
</div>

For responsive layouts with collapsible sidebar, see layouts reference.

Data Tables

Basic admin table with Skeleton styling:

<script>
  import { Table } from '@skeletonlabs/skeleton-svelte';

  let users = $state([
    { id: 1, name: 'John Doe', email: '[email protected]', role: 'Admin' },
    { id: 2, name: 'Jane Smith', email: '[email protected]', role: 'User' },
  ]);
</script>

<div class="overflow-x-auto rounded-lg border border-surface-200-800">
  <table class="w-full">
    <thead class="bg-surface-100-900">
      <tr>
        <th class="p-3 text-left text-surface-950-50">Name</th>
        <th class="p-3 text-left text-surface-950-50">Email</th>
        <th class="p-3 text-left text-surface-950-50">Role</th>
        <th class="p-3 text-left text-surface-950-50">Actions</th>
      </tr>
    </thead>
    <tbody>
      {#each users as user}
        <tr class="border-t border-surface-200-800 hover:bg-surface-100-900">
          <td class="p-3">{user.name}</td>
          <td class="p-3">{user.email}</td>
          <td class="p-3">
            <span class="badge variant-filled">{user.role}</span>
          </td>
          <td class="p-3">
            <button class="btn btn-sm variant-ghost">Edit</button>
          </td>
        </tr>
      {/each}
    </tbody>
  </table>
</div>

For pagination, sorting, and filtering, see data-tables reference.

Forms

Basic Form Pattern

<script>
  let formData = $state({
    email: '',
    password: '',
    remember: false
  });

  async function handleSubmit() {
    // Handle form submission
  }
</script>

<form onsubmit={handleSubmit} class="space-y-4">
  <div>
    <label for="email" class="label">Email</label>
    <input
      type="email"
      id="email"
      bind:value={formData.email}
      class="input variant-form"
      placeholder="[email protected]"
    />
  </div>

  <div>
    <label for="password" class="label">Password</label>
    <input
      type="password"
      id="password"
      bind:value={formData.password}
      class="input variant-form"
    />
  </div>

  <div class="flex items-center gap-2">
    <input type="checkbox" id="remember" bind:checked={formData.remember} />
    <label for="remember" class="label">Remember me</label>
  </div>

  <button type="submit" class="btn variant-filled">Sign In</button>
</form>

For validation, file uploads, and advanced form patterns, see forms reference.

Navigation

Sidebar Navigation

<script>
  import { page } from '$app/stores';

  const navItems = [
    { href: '/', label: 'Dashboard', icon: 'dashboard' },
    { href: '/users', label: 'Users', icon: 'users' },
    { href: '/analytics', label: 'Analytics', icon: 'chart' },
    { href: '/settings', label: 'Settings', icon: 'settings' },
  ];
</script>

<nav class="flex flex-col gap-1">
  {#each navItems as item}
    <a
      href={item.href}
      class="flex items-center gap-3 p-3 rounded-lg transition-colors
        {$page.url.pathname === item.href
          ? 'bg-primary-500 text-white'
          : 'hover:bg-surface-200-800'}"
    >
      <span class="w-5 h-5">{item.icon}</span>
      <span>{item.label}</span>
    </a>
  {/each}
</nav>

Breadcrumbs

<nav aria-label="Breadcrumb">
  <ol class="flex items-center gap-2 text-sm">
    <li><a href="/" class="hover:text-primary-500">Home</a></li>
    <li class="text-surface-500">/</li>
    <li><a href="/users" class="hover:text-primary-500">Users</a></li>
    <li class="text-surface-500">/</li>
    <li class="text-surface-950-50 font-medium">Edit User</li>
  </ol>
</nav>

For complete navigation patterns, see navigation reference.

Common Components

Cards

<div class="card bg-surface-50-950 border border-surface-200-800 p-4 rounded-xl">
  <h3 class="text-lg font-semibold text-surface-950-50">Card Title</h3>
  <p class="text-surface-500 mt-2">Card description text here.</p>
</div>

Badges

<span class="badge variant-filled">Default</span>
<span class="badge variant-filled-primary">Primary</span>
<span class="badge variant-filled-secondary">Secondary</span>
<span class="badge variant-filled-success">Success</span>
<span class="badge variant-filled-warning">Warning</span>
<span class="badge variant-filled-error">Error</span>

Buttons

<button class="btn variant-filled">Filled</button>
<button class="btn variant-outline">Outline</button>
<button class="btn variant-ghost">Ghost</button>
<button class="btn variant-filled-primary">Primary</button>
<button class="btn variant-filled-error">Destructive</button>

Dialogs

<script>
  import { Dialog } from '@skeletonlabs/skeleton-svelte';

  let open = $state(false);
</script>

<button class="btn" onclick={() => open = true}>Open Dialog</button>

<Dialog bind:open>
  <div class="p-6 bg-surface-50-950 rounded-xl">
    <h2 class="text-xl font-bold">Dialog Title</h2>
    <p class="mt-2 text-surface-500">Dialog content here.</p>
    <div class="flex justify-end gap-2 mt-4">
      <button class="btn variant-ghost" onclick={() => open = false}>Cancel</button>
      <button class="btn variant-filled">Confirm</button>
    </div>
  </div>
</Dialog>

For complete component reference, see components reference.

Toast Notifications

<script>
  import { toast } from '@skeletonlabs/skeleton-svelte';

  function showSuccess() {
    toast.success({ title: 'Success', body: 'Operation completed!' });
  }

  function showError() {
    toast.error({ title: 'Error', body: 'Something went wrong.' });
  }
</script>

Responsive Design

Breakpoints

BreakpointMin WidthUsage
sm640pxsm:block
md768pxmd:grid-cols-2
lg1024pxlg:flex
xl1280pxxl:w-64
2xl1536px2xl:container

Mobile-First Pattern

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
  <div class="card">Card 1</div>
  <div class="card">Card 2</div>
  <div class="card">Card 3</div>
  <div class="card">Card 4</div>
</div>

Accessibility

Semantic HTML

Always use semantic elements:

<header><!-- Logo, navigation --></header>
<aside><!-- Sidebar navigation --></aside>
<main><!-- Primary content --></main>
<nav><!-- Navigation menus --></nav>
<footer><!-- Footer content --></footer>

ARIA Labels

<button aria-label="Close menu">
  <svg aria-hidden="true">...</svg>
</button>

<nav aria-label="Main navigation">
  <!-- nav items -->
</nav>

Focus Management

<script>
  import { tick } from 'svelte';

  async function openModal() {
    modalOpen = true;
    await tick();
    document.getElementById('first-focusable')?.focus();
  }
</script>

Color Tokens

Skeleton provides semantic color tokens that adapt to dark/light mode:

TokenLight ModeDark Mode
bg-surface-50-950Light grayNear black
bg-surface-100-900LighterDarker
text-surface-950-50Dark textLight text
border-surface-200-800Light borderDark border

Use the dual-token pattern for automatic theme adaptation:

<div class="bg-surface-50-950 text-surface-950-50 border-surface-200-800">
  Adapts to theme automatically
</div>

Reference Files

Load these files on demand based on the task:

  • Installation — Read when setting up a new project or encountering build/config errors
  • Layouts — Read when building page structure, sidebar layouts, or responsive grids
  • Data Tables — Read when implementing tables with sorting, pagination, or search
  • Forms — Read when building forms with validation, file uploads, or multi-step flows
  • Navigation — Read when implementing sidebar menus, breadcrumbs, or app bars
  • Auth Pages — Read when building login, register, or password reset pages
  • Components — Read when using Skeleton badges, buttons, cards, dialogs, or toasts
  • Templates — Read when you need a complete page template (dashboard, users list, settings)

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.