{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"c-sortable-4","type":"registry:block","title":"Sortable playlist with frame","description":"Sortable playlist with frame","dependencies":[],"registryDependencies":["@reui/badge","@reui/frame","@reui/sortable"],"files":[{"path":"c-sortable-4.tsx","type":"registry:block","content":"\"use client\"\n\nimport { useState } from \"react\"\nimport { Badge } from \"@/components/reui/badge\"\nimport {\n  Frame,\n  FrameDescription,\n  FrameHeader,\n  FramePanel,\n  FrameTitle,\n} from \"@/components/reui/frame\"\nimport {\n  Sortable,\n  SortableItem,\n  SortableItemHandle,\n} from \"@/components/reui/sortable\"\n\nimport { IconPlaceholder } from \"@/app/(create)/components/icon-placeholder\"\n\ninterface Track {\n  id: string\n  title: string\n  artist: string\n  album: string\n  duration: string\n  plays: string\n  active?: boolean\n}\n\nconst defaultTracks: Track[] = [\n  {\n    id: \"1\",\n    title: \"Midnight City\",\n    artist: \"M83\",\n    album: \"Hurry Up, We're Dreaming\",\n    duration: \"4:03\",\n    plays: \"1.2B\",\n    active: true,\n  },\n  {\n    id: \"2\",\n    title: \"Digital Love\",\n    artist: \"Daft Punk\",\n    album: \"Discovery\",\n    duration: \"4:58\",\n    plays: \"845M\",\n  },\n  {\n    id: \"3\",\n    title: \"Starlight\",\n    artist: \"Muse\",\n    album: \"Black Holes\",\n    duration: \"3:59\",\n    plays: \"720M\",\n  },\n  {\n    id: \"4\",\n    title: \"Take On Me\",\n    artist: \"a-ha\",\n    album: \"Hunting High and Low\",\n    duration: \"3:48\",\n    plays: \"1.8B\",\n  },\n  {\n    id: \"5\",\n    title: \"Blue Monday\",\n    artist: \"New Order\",\n    album: \"Power, Corruption\",\n    duration: \"7:29\",\n    plays: \"530M\",\n  },\n]\n\nexport function Pattern() {\n  const [tracks, setTracks] = useState<Track[]>(defaultTracks)\n\n  return (\n    <div className=\"mx-auto w-full max-w-md\">\n      <Frame spacing=\"xs\">\n        <FrameHeader>\n          <div className=\"flex items-center justify-between\">\n            <div>\n              <FrameTitle>Queue</FrameTitle>\n              <FrameDescription>{tracks.length} tracks</FrameDescription>\n            </div>\n            <Badge variant=\"outline\" size=\"sm\">\n              <IconPlaceholder\n                lucide=\"ListMusicIcon\"\n                tabler=\"IconPlaylist\"\n                hugeicons=\"PlayListIcon\"\n                phosphor=\"PlaylistIcon\"\n                remixicon=\"RiPlayListLine\"\n                className=\"size-3\"\n              />\n              Playlist\n            </Badge>\n          </div>\n        </FrameHeader>\n        <Sortable\n          value={tracks}\n          onValueChange={setTracks}\n          getItemValue={(item) => item.id}\n          strategy=\"vertical\"\n          className=\"space-y-0.5\"\n        >\n          {tracks.map((track, index) => (\n            <SortableItem key={track.id} value={track.id}>\n              <FramePanel className=\"p-0!\">\n                <div className=\"group flex items-center gap-3 px-3 py-2.5\">\n                  <SortableItemHandle className=\"text-muted-foreground hover:text-foreground\">\n                    <IconPlaceholder\n                      lucide=\"GripVerticalIcon\"\n                      tabler=\"IconGripVertical\"\n                      hugeicons=\"DragDropVerticalIcon\"\n                      phosphor=\"DotsSixVerticalIcon\"\n                      remixicon=\"RiDraggable\"\n                      className=\"size-4\"\n                    />\n                  </SortableItemHandle>\n                  <div className=\"bg-muted flex size-9 shrink-0 items-center justify-center rounded-md\">\n                    <IconPlaceholder\n                      lucide=\"MusicIcon\"\n                      tabler=\"IconMusic\"\n                      hugeicons=\"MusicNote03Icon\"\n                      phosphor=\"MusicNotesIcon\"\n                      remixicon=\"RiMusic2Line\"\n                      className=\"text-muted-foreground size-4\"\n                    />\n                  </div>\n                  <div className=\"min-w-0 flex-1\">\n                    <p\n                      className={`truncate text-sm font-medium ${track.active ? \"text-primary\" : \"\"}`}\n                    >\n                      {track.title}\n                      {track.active && (\n                        <Badge\n                          variant=\"primary-light\"\n                          size=\"xs\"\n                          className=\"ms-1.5 align-middle\"\n                        >\n                          Playing\n                        </Badge>\n                      )}\n                    </p>\n                    <p className=\"text-muted-foreground truncate text-xs\">\n                      {track.artist} &middot; {track.album}\n                    </p>\n                  </div>\n                  <div className=\"flex items-center gap-3\">\n                    <span className=\"text-muted-foreground hidden text-xs tabular-nums sm:inline\">\n                      {track.plays}\n                    </span>\n                    <span className=\"text-muted-foreground text-xs tabular-nums\">\n                      {track.duration}\n                    </span>\n                  </div>\n                </div>\n              </FramePanel>\n            </SortableItem>\n          ))}\n        </Sortable>\n      </Frame>\n    </div>\n  )\n}","target":"components/examples/c-sortable-4.tsx"}],"meta":{"order":4,"gridSize":1}}