Index of every page on this site: llms.txt
All skills
harlan-zw avatar

/nuxt-frontend-design

@9c94eb4
Run it yourself

Build or polish Nuxt UI v4+ pages and design systems. Use for landing pages, dashboards, tokens, motion, or generic-looking UX.

Use this Skill: https://skilld.dev/gh/harlan-zw/harlan-agent-kit/nuxt-frontend-design

Nothing lands on disk. Nothing to clean up.

Fork this Skill

Edit a local copy. It keeps the author and licence.

referencescomponentsfeedback.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Feedback & Overlay Patterns

Toasts, modals, confirmations, and state communication.


Toast Notifications

Wrap useToast() in a typed useAppToast() composable in app/composables/, with preset icons and colors per status, so call sites never repeat icon/color choices.

const toast = useAppToast()

// String shorthand — just a title
toast.success('Saved')

// Full form
toast.error({ title: 'Failed to save', description: error.message })
toast.warning({ title: 'Unsaved changes', description: 'Save before leaving.' })
toast.info({ title: 'New version available', actions: [{ label: 'Reload', click: reload }] })

Why the wrapper: direct useToast().add({ color, icon, ... }) calls scatter status semantics across the codebase. A typed .success / .info / .warning / .error API keeps status meaning in one place, matches call-sites to intent, and makes find-all-errors-in-the-app a single grep.

Undo Pattern (prefer over confirm dialogs)

const toast = useAppToast()

function deleteItem(id: string) {
  const backup = items.value.find(i => i.id === id)
  items.value = items.value.filter(i => i.id !== id)

  toast.info({
    title: 'Deleted',
    actions: [{
      label: 'Undo',
      click: () => { items.value.push(backup!) },
    }],
  })

  setTimeout(() => api.delete(id), 5000)
}

Modal Dialogs

<script setup lang="ts">
const open = ref(false)
</script>

<template>
  <UButton @click="open = true">
    Open Settings
  </UButton>

  <UModal v-model:open="open">
    <template #header>
      <h3 class="text-lg font-semibold">
        Settings
      </h3>
    </template>

    <div class="p-6">
      <!-- Modal content -->
    </div>

    <template #footer>
      <div class="flex justify-end gap-3">
        <UButton variant="outline" @click="open = false">
          Cancel
        </UButton>
        <UButton @click="save">
          Save
        </UButton>
      </div>
    </template>
  </UModal>
</template>

Confirmation (when undo isn't possible)

<UModal v-model:open="confirmOpen">
  <div class="p-6 text-center">
    <UIcon name="i-lucide-alert-triangle" class="text-4xl text-warning mb-4" />
    <h3 class="text-lg font-semibold">Delete "{{ project.name }}"?</h3>
    <p class="text-muted mt-2">All files and settings will be permanently removed.</p>
    <div class="flex justify-center gap-3 mt-6">
      <UButton variant="outline" @click="confirmOpen = false">Keep project</UButton>
      <UButton color="error" @click="confirmDelete">Delete project</UButton>
    </div>
  </div>
</UModal>

Rules:

  • Prefer "Undo" toasts over confirmation dialogs — users click through confirmations mindlessly
  • Only use confirmation for truly irreversible, high-cost, or batch operations
  • Button labels must be verb-object pairs — "Delete project" not "OK", "Keep project" not "Cancel"
  • Explain specific consequences — "All files and settings will be permanently removed" not "This action cannot be undone"

Dropdown Menus

<UDropdownMenu :items="[
  [
    { label: 'Edit', icon: 'i-lucide-pencil' },
    { label: 'Duplicate', icon: 'i-lucide-copy' }
  ],
  [
    { label: 'Delete', icon: 'i-lucide-trash-2', color: 'error' }
  ]
]"
>
  <UButton icon="i-lucide-ellipsis-vertical" variant="ghost" />
</UDropdownMenu>

Tooltips

<UTooltip text="Copy to clipboard">
  <UButton icon="i-lucide-copy" variant="ghost" />
</UTooltip>

Alert Banners

<UAlert
  title="New version available"
  description="Update to v2.0 for new features."
  icon="i-lucide-info"
  color="info"
  :actions="[{ label: 'Update', click: update }]"
/>

Empty States

Use UEmpty (v4+) for simple cases:

<UEmpty
  icon="i-lucide-inbox"
  title="No messages"
  description="When you receive messages, they'll appear here."
  :actions="[{ label: 'Compose', variant: 'outline', click: compose }]"
/>

Richer empty states want an action preset (refresh / reset / clear / back) and an optional footer slot. Build it once as a component in app/components/ and reuse it.

<UiNoData
  icon="i-lucide-search-x"
  title="No results"
  message="Try clearing filters or broadening your search."
  action="reset"
  @action="clearFilters"
/>

Source: SKILL.md on GitHub

skilld matched fixed text patterns in SKILL.md and file names. Patterns miss obfuscated code.

skilld run checks every file with the same patterns. It asks for approval before it loads a Skill with a behavior marked Needs approval.

1 warning3mo3 checks · Risk MEDIUM
  • Gen Agent Trust Hub3mo

    The skill utilizes dynamic context injection to probe the local environment and executes external CLI tools via npx, including an unverified package for CSS analysis.

  • Socket3mo

    No alerts

  • Snyk3mo

    Risk: LOW · No issues

Signed by skilld at 9c94eb4. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated last month
argument-hint
[component/page/area]
effort
max

README badge

README badge for harlan-zw/harlan-agent-kit/nuxt-frontend-design