{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "search-results-page",
  "title": "Search Results Page",
  "type": "registry:page",
  "files": [
    {
      "path": "packages/registry-svelte/blocks/search-results-page/SearchResultsPage.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Component } from 'svelte'\n\n  export interface SearchResult {\n    id: string\n    icon: Component\n    title: string\n    path: string\n    snippet: string\n    type: string\n    updated: string\n  }\n\n  export interface FacetOption {\n    id: string\n    label: string\n    count: number\n  }\n\n  export interface FacetGroup {\n    id: string\n    label: string\n    options: FacetOption[]\n  }\n\n  export interface SearchResultsPageProps {\n    class?: string\n  }\n</script>\n\n<script lang=\"ts\">\n  import { BookOpen, FileText, GitBranch, MessageSquare, Search, Users, Video } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n  import { Badge } from '$lib/components/ui/badge'\n  import { Button } from '$lib/components/ui/button'\n  import { Checkbox } from '$lib/components/ui/checkbox'\n  import { Chip } from '$lib/components/ui/chip'\n  import { Input } from '$lib/components/ui/input'\n\n  let { class: className }: SearchResultsPageProps = $props()\n\n  let query = $state('onboarding flows')\n\n  let chips = $state([\n    { id: 'type-docs', label: 'Type: Docs' },\n    { id: 'team-product', label: 'Team: Product' },\n  ])\n\n  function removeChip(id: string) {\n    chips = chips.filter((chip) => chip.id !== id)\n  }\n\n  function clearAll() {\n    chips = []\n  }\n\n  const facetGroups: FacetGroup[] = [\n    {\n      id: 'type',\n      label: 'Type',\n      options: [\n        { id: 'type-docs', label: 'Docs', count: 18 },\n        { id: 'type-guides', label: 'Guides', count: 11 },\n        { id: 'type-video', label: 'Video', count: 7 },\n        { id: 'type-discussion', label: 'Discussion', count: 6 },\n      ],\n    },\n    {\n      id: 'team',\n      label: 'Team',\n      options: [\n        { id: 'team-product', label: 'Product', count: 14 },\n        { id: 'team-engineering', label: 'Engineering', count: 16 },\n        { id: 'team-design', label: 'Design', count: 8 },\n        { id: 'team-support', label: 'Support', count: 4 },\n      ],\n    },\n  ]\n\n  let activeFacets = $state(new Set(['type-docs', 'team-product']))\n\n  function toggleFacet(id: string, checked: boolean) {\n    const next = new Set(activeFacets)\n    if (checked) next.add(id)\n    else next.delete(id)\n    activeFacets = next\n  }\n\n  const results: SearchResult[] = [\n    {\n      id: 'r1',\n      icon: BookOpen,\n      title: 'Onboarding flows: design your first-run experience',\n      path: 'docs.acme.dev / guides / onboarding-flows',\n      snippet:\n        'Learn how to compose onboarding flows from checklists, tours, and progressive disclosure so new users reach their first aha moment faster.',\n      type: 'Docs',\n      updated: '2 days ago',\n    },\n    {\n      id: 'r2',\n      icon: FileText,\n      title: 'Checklist API reference for onboarding flows',\n      path: 'docs.acme.dev / api / checklist',\n      snippet:\n        'Full reference for the Checklist primitive used to drive onboarding flows, including step completion events, persistence, and theming.',\n      type: 'Reference',\n      updated: '5 hours ago',\n    },\n    {\n      id: 'r3',\n      icon: Video,\n      title: 'Video walkthrough: building onboarding flows in 20 minutes',\n      path: 'learn.acme.dev / videos / onboarding-flows-walkthrough',\n      snippet:\n        'A hands-on screencast that builds a complete onboarding flow with branching steps, skippable tours, and analytics instrumentation.',\n      type: 'Video',\n      updated: '1 week ago',\n    },\n    {\n      id: 'r4',\n      icon: MessageSquare,\n      title: 'How do you measure completion of onboarding flows?',\n      path: 'community.acme.dev / discussions / 4821',\n      snippet:\n        'Community thread comparing activation-rate funnels, step-drop-off charts, and qualitative surveys for measuring onboarding flow success.',\n      type: 'Discussion',\n      updated: '3 days ago',\n    },\n    {\n      id: 'r5',\n      icon: GitBranch,\n      title: 'Example repo: onboarding flows with A/B-tested variants',\n      path: 'github.com / acme / examples / onboarding-ab-test',\n      snippet:\n        'Runnable example that splits new signups into two onboarding flow variants and reports which one converts better to first project creation.',\n      type: 'Example',\n      updated: '2 weeks ago',\n    },\n    {\n      id: 'r6',\n      icon: Users,\n      title: 'Playbook: personalizing onboarding flows by team role',\n      path: 'docs.acme.dev / playbooks / role-based-onboarding',\n      snippet:\n        'Patterns for tailoring onboarding flows to admins, editors, and viewers, with sample copy, suggested defaults, and rollout checklists.',\n      type: 'Guide',\n      updated: '4 days ago',\n    },\n  ]\n\n  let page = $state(1)\n  const totalPages = 3\n\n  const resultRange = $derived.by(() => {\n    const start = (page - 1) * 6 + 1\n    return `${start}-${start + results.length - 1}`\n  })\n</script>\n\n<div data-slot=\"search-results-page\" class={cn('w-full space-y-6', className)}>\n  <div class=\"space-y-3\">\n    <div class=\"relative max-w-xl\">\n      <Search\n        aria-hidden=\"true\"\n        class=\"text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2\"\n      />\n      <Input bind:value={query} type=\"search\" placeholder=\"Search...\" class=\"h-11 pl-9 text-base\" />\n    </div>\n    <p class=\"text-muted-foreground text-sm\">{resultRange} of 42 results for &ldquo;{query}&rdquo;</p>\n  </div>\n\n  {#if chips.length > 0}\n    <div class=\"flex flex-wrap items-center gap-2\">\n      {#each chips as chip (chip.id)}\n        <Chip variant=\"outline\" size=\"sm\" closable onclose={() => removeChip(chip.id)}>\n          {chip.label}\n        </Chip>\n      {/each}\n      <Button variant=\"link\" size=\"sm\" class=\"text-muted-foreground h-auto min-h-6 px-2\" onclick={clearAll}>\n        Clear all\n      </Button>\n    </div>\n  {/if}\n\n  <div class=\"flex gap-8\">\n    <aside class=\"hidden w-48 shrink-0 space-y-6 lg:block\" aria-label=\"Filters\">\n      {#each facetGroups as group (group.id)}\n        <div>\n          <h3 class=\"text-muted-foreground mb-3 text-xs font-medium tracking-wider uppercase\">\n            {group.label}\n          </h3>\n          <ul class=\"space-y-2.5\">\n            {#each group.options as option (option.id)}\n              <li>\n                <label for={`${group.id}-${option.id}`} class=\"flex cursor-pointer items-center gap-2 text-sm\">\n                  <Checkbox\n                    id={`${group.id}-${option.id}`}\n                    checked={activeFacets.has(option.id)}\n                    onCheckedChange={(v) => toggleFacet(option.id, v === true)}\n                  />\n                  <span>{option.label}</span>\n                  <span class=\"text-muted-foreground ml-auto text-xs tabular-nums\">{option.count}</span>\n                </label>\n              </li>\n            {/each}\n          </ul>\n        </div>\n      {/each}\n    </aside>\n\n    <div class=\"min-w-0 flex-1\">\n      <ol class=\"divide-border divide-y\">\n        {#each results as result (result.id)}\n          {@const ResultIcon = result.icon}\n          <li>\n            <a\n              href=\"#\"\n              class=\"hover:bg-muted/50 focus-visible:ring-ring block rounded-lg p-4 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n            >\n              <div class=\"flex gap-4\">\n                <div\n                  class=\"bg-muted/50 text-muted-foreground flex size-10 shrink-0 items-center justify-center rounded-md border\"\n                >\n                  <ResultIcon aria-hidden=\"true\" class=\"size-5\" />\n                </div>\n                <div class=\"min-w-0 space-y-1\">\n                  <p class=\"truncate font-medium\">{result.title}</p>\n                  <p class=\"text-muted-foreground truncate text-xs\">{result.path}</p>\n                  <p class=\"text-muted-foreground line-clamp-2 text-sm\">{result.snippet}</p>\n                  <div class=\"flex items-center gap-3 pt-1\">\n                    <Badge variant=\"secondary\">{result.type}</Badge>\n                    <span class=\"text-muted-foreground text-xs\">Updated {result.updated}</span>\n                  </div>\n                </div>\n              </div>\n            </a>\n          </li>\n        {/each}\n      </ol>\n\n      <nav class=\"flex items-center justify-between pt-4\" aria-label=\"Pagination\">\n        <Button variant=\"outline\" size=\"sm\" disabled={page === 1} onclick={() => page--}>Previous</Button>\n        <div class=\"flex items-center gap-1\">\n          {#each Array.from({ length: totalPages }, (_, i) => i + 1) as n (n)}\n            <Button\n              variant={n === page ? 'outline' : 'ghost'}\n              size=\"icon-sm\"\n              aria-current={n === page ? 'page' : undefined}\n              onclick={() => (page = n)}\n            >\n              {n}\n            </Button>\n          {/each}\n        </div>\n        <Button variant=\"outline\" size=\"sm\" disabled={page === totalPages} onclick={() => page++}>Next</Button>\n      </nav>\n    </div>\n  </div>\n</div>\n",
      "type": "registry:page",
      "target": "~/src/lib/components/blocks/search-results-page/SearchResultsPage.svelte"
    }
  ],
  "dependencies": [
    "@lucide/svelte"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/svelte/badge.json",
    "https://uipkge.dev/r/svelte/button.json",
    "https://uipkge.dev/r/svelte/checkbox.json",
    "https://uipkge.dev/r/svelte/chip.json",
    "https://uipkge.dev/r/svelte/input.json"
  ],
  "description": "Full search results page: large pre-filled search input with result count, removable filter chips with clear-all, a left facet sidebar with Type and Team checkbox groups (hidden below lg), six result rows with icon tiles, titles, paths, snippets, and type/updated meta, plus a Previous/Next pagination footer. Chips and facets are interactive; swap the stub rows for your search source.",
  "categories": [
    "layout",
    "app"
  ]
}