sanity-plugin-workspace-home

3.0.213.0.22
~

Modified (2 files)

Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
 {
   "name": "sanity-plugin-workspace-home",
-  "version": "3.0.21",
+  "version": "3.0.22",
   "description": "A home screen for your multi-workspace Sanity Studio",
   "keywords": [
     "sanity",
     "sanity-plugin"
@@ -26,21 +26,21 @@
     ".": "./dist/index.js",
     "./package.json": "./package.json"
   },
   "dependencies": {
-    "@sanity/icons": "^5.2.1",
-    "@sanity/ui": "^4.0.4",
-    "react-is": "^19.2.8"
+    "@sanity/icons": "^5.2.2",
+    "@sanity/ui": "^4.2.7",
+    "react-is": "^19.3.0"
   },
   "devDependencies": {
     "@sanity/tsconfig": "^2.2.1",
-    "@sanity/tsdown-config": "^0.26.0",
+    "@sanity/tsdown-config": "^0.27.1",
     "@types/node": "^24.13.3",
-    "@types/react": "^19.2.18",
-    "@types/react-is": "^19.2.0",
-    "oxc-transform-react": "^0.145.0",
-    "react": "^19.2.8",
-    "sanity": "^6.10.1",
+    "@types/react": "^19.3.0",
+    "@types/react-is": "^19.3.0",
+    "oxc-transform-react": "^0.147.0",
+    "react": "^19.3.0",
+    "sanity": "^6.16.0",
     "styled-components": "^6.5.3",
     "tsdown": "^0.22.14"
   },
   "peerDependencies": {
Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["createIcon(icon)","useMemo(() => createIcon(icon), [icon])","[2, 3, 4, 4]","() => setActiveWorkspace(name)","iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null","[1, 2, 3, 3]","<Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>","title || name","subtitle ? <Text muted>{subtitle}</Text> : null","<Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>","<Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>","<Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>","<Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>","<Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>","[2, 3, 3, 3]","!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null","<Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>","<Grid gridTemplateColumns={5} gap={[2, 3, 4, 4]} paddingY={1}>\n        <Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>\n        <Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>\n        <Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>\n        {/* <Button\n          mode={isFavourite ? 'default' : 'bleed'}\n          tone={isFavourite ? 'primary' : 'default'}\n          icon={StarIcon}\n          title=\"Favorite\"\n          onClick={() => {\n            setIsFavourite(!isFavourite)\n            setFavoriteWorkspace()\n          }}\n        /> */}\n      </Grid>","<Card borderTop={Boolean(index)} tone=\"default\">\n      <Grid gridTemplateColumns={5} gap={[2, 3, 4, 4]} paddingY={1}>\n        <Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>\n        <Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>\n        <Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>\n        {/* <Button\n          mode={isFavourite ? 'default' : 'bleed'}\n          tone={isFavourite ? 'primary' : 'default'}\n          icon={StarIcon}\n          title=\"Favorite\"\n          onClick={() => {\n            setIsFavourite(!isFavourite)\n            setFavoriteWorkspace()\n          }}\n        /> */}\n      </Grid>\n    </Card>","Boolean(index)","useWorkspaces()","(e: React.ChangeEvent<HTMLInputElement>) => {\n      setQuery(e.target.value)\n    }","useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      setQuery(e.target.value)\n    },\n    [setQuery],\n  )","workspaces.filter((workspace) => {\n      return (\n        workspace.name.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.dataset.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.title.toLowerCase().includes(query.toLowerCase())\n      )\n    })","useMemo(() => {\n    return workspaces.filter((workspace) => {\n      return (\n        workspace.name.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.dataset.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.title.toLowerCase().includes(query.toLowerCase())\n      )\n    })\n  }, [workspaces, query])","() => {\n    const handleKeypress = (event: KeyboardEvent) => {\n      // Ignore if search query exists or search input is focused\n      if (query || searchInput.current === document.activeElement) {\n        return\n      }\n\n      const index = parseInt(event.key, 10) - 1\n      if (index >= 0 && index < workspaces.length) {\n        setActiveWorkspace(workspaces[index]!.name)\n      }\n    }\n\n    window.addEventListener('keypress', handleKeypress)\n\n    return () => {\n      window.removeEventListener('keypress', handleKeypress)\n    }\n  }","[query, workspaces, setActiveWorkspace]","workspaces.length","[4, 5, 6, 6]","<Heading>Workspaces</Heading>","[2, 3, 4, 4]","<Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>","<Stack gap={2}>\n                  <Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>\n                  <TextInput ref={searchInput} value={query} onChange={handleQuery} />\n                </Stack>","<Box>\n                  {filteredWorkspaces.map((workspace, index) => (\n                    <WorkspacePreview\n                      key={workspace.name}\n                      workspace={workspace}\n                      index={index}\n                      query={query}\n                    />\n                  ))}\n                </Box>","workspace","index","<TallCard tone=\"transparent\">\n      <Flex direction=\"column\" padding={[4, 5, 6, 6]}>\n        <Container>\n          <Stack gap={4}>\n            <Heading>Workspaces</Heading>\n            <Card padding={[2, 3, 4, 4]} radius={3} shadow={2}>\n              <Stack gap={3}>\n                <Stack gap={2}>\n                  <Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>\n                  <TextInput ref={searchInput} value={query} onChange={handleQuery} />\n                </Stack>\n                <Box>\n                  {filteredWorkspaces.map((workspace, index) => (\n                    <WorkspacePreview\n                      key={workspace.name}\n                      workspace={workspace}\n                      index={index}\n                      query={query}\n                    />\n                  ))}\n                </Box>\n              </Stack>\n            </Card>\n          </Stack>\n        </Container>\n      </Flex>\n    </TallCard>"],"sources":["../src/components/WorkspacePreview.tsx","../src/components/WorkspaceHome.tsx","../src/index.ts"],"sourcesContent":["import {DatabaseIcon} from '@sanity/icons/Database'\nimport {Box, Button, Card, Flex, Grid, Hotkeys, Stack, Text} from '@sanity/ui'\nimport {isValidElement, useMemo} from 'react'\nimport {isValidElementType} from 'react-is'\nimport {useActiveWorkspace, type WorkspaceSummary} from 'sanity'\nimport {styled} from 'styled-components'\n\nconst createIcon = (Icon: React.ComponentType | React.ReactNode) => {\n  if (isValidElementType(Icon)) return <Icon />\n  if (isValidElement(Icon)) return Icon\n  return undefined\n}\n\nconst MediaCard = styled(Card)`\n  width: 35px;\n  height: 35px;\n\n  svg {\n    width: 100%;\n    height: 100%;\n  }\n`\n\nexport type WorkspacePreviewProps = {\n  workspace: WorkspaceSummary\n  index: number\n  query: string\n}\n\nexport default function WorkspacePreview(props: WorkspacePreviewProps): React.JSX.Element {\n  const {workspace, index, query} = props\n  const {icon, title, name, subtitle, dataset} = workspace\n\n  const {setActiveWorkspace} = useActiveWorkspace()\n  const iconComponent = useMemo(() => createIcon(icon), [icon])\n\n  // TODO: Favorites feature\n  // get favorite workspace name from localStorage\n  //   const favoriteWorkspace = localStorage.getItem('favoriteWorkspace')\n  //   save local state to force re-render\n  //   const [isFavourite, setIsFavourite] = React.useState(favoriteWorkspace === name)\n\n  // set favorite workspace name to localStorage\n  //   const setFavoriteWorkspace = useCallback(() => {\n  //     localStorage.setItem('favoriteWorkspace', name)\n  //   }, [name])\n\n  const hotKeyIndex = index + 1 === 10 ? 0 : index + 1\n\n  return (\n    <Card borderTop={Boolean(index)} tone=\"default\">\n      <Grid gridTemplateColumns={5} gap={[2, 3, 4, 4]} paddingY={1}>\n        <Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>\n        <Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>\n        <Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>\n        {/* <Button\n          mode={isFavourite ? 'default' : 'bleed'}\n          tone={isFavourite ? 'primary' : 'default'}\n          icon={StarIcon}\n          title=\"Favorite\"\n          onClick={() => {\n            setIsFavourite(!isFavourite)\n            setFavoriteWorkspace()\n          }}\n        /> */}\n      </Grid>\n    </Card>\n  )\n}\n","import {Box, Card, Container, Flex, Heading, Stack, Text, TextInput} from '@sanity/ui'\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {useActiveWorkspace, useWorkspaces} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport WorkspacePreview from './WorkspacePreview'\n\nconst TallCard = styled(Card)`\n  min-height: 100%;\n`\n\nexport default function WorkspaceHome(): React.JSX.Element {\n  const [, ...workspaces] = useWorkspaces()\n  const {setActiveWorkspace} = useActiveWorkspace()\n\n  // Handle search query\n  const [query, setQuery] = useState('')\n  const searchInput = useRef(null)\n  const handleQuery = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      setQuery(e.target.value)\n    },\n    [setQuery],\n  )\n\n  // filter workspaces if name, dataset or title matches query\n  const filteredWorkspaces = useMemo(() => {\n    return workspaces.filter((workspace) => {\n      return (\n        workspace.name.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.dataset.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.title.toLowerCase().includes(query.toLowerCase())\n      )\n    })\n  }, [workspaces, query])\n\n  // Listen to keypress of workspace index\n  useEffect(() => {\n    const handleKeypress = (event: KeyboardEvent) => {\n      // Ignore if search query exists or search input is focused\n      if (query || searchInput.current === document.activeElement) {\n        return\n      }\n\n      const index = parseInt(event.key, 10) - 1\n      if (index >= 0 && index < workspaces.length) {\n        setActiveWorkspace(workspaces[index]!.name)\n      }\n    }\n\n    window.addEventListener('keypress', handleKeypress)\n\n    return () => {\n      window.removeEventListener('keypress', handleKeypress)\n    }\n  }, [query, workspaces, setActiveWorkspace])\n\n  return (\n    <TallCard tone=\"transparent\">\n      <Flex direction=\"column\" padding={[4, 5, 6, 6]}>\n        <Container>\n          <Stack gap={4}>\n            <Heading>Workspaces</Heading>\n            <Card padding={[2, 3, 4, 4]} radius={3} shadow={2}>\n              <Stack gap={3}>\n                <Stack gap={2}>\n                  <Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>\n                  <TextInput ref={searchInput} value={query} onChange={handleQuery} />\n                </Stack>\n                <Box>\n                  {filteredWorkspaces.map((workspace, index) => (\n                    <WorkspacePreview\n                      key={workspace.name}\n                      workspace={workspace}\n                      index={index}\n                      query={query}\n                    />\n                  ))}\n                </Box>\n              </Stack>\n            </Card>\n          </Stack>\n        </Container>\n      </Flex>\n    </TallCard>\n  )\n}\n","import '@sanity/ui/styles.css'\nimport {HomeIcon} from '@sanity/icons/Home'\nimport {definePlugin, type Plugin, type WorkspaceOptions} from 'sanity'\n\nimport WorkspaceHome from './components/WorkspaceHome'\n\nexport const workspaceHome: Plugin = definePlugin(() => {\n  return {\n    name: 'sanity-plugin-workspace-home',\n    tools: [\n      {\n        title: 'Workspace Home',\n        name: 'workspace-home',\n        icon: HomeIcon,\n        component: WorkspaceHome,\n      },\n    ],\n  }\n})\n\ntype WorkspaceHomeConfigProps = {\n  projectId: string\n  dataset: string\n}\n\nexport const workspaceHomeConfig = ({\n  projectId,\n  dataset,\n}: WorkspaceHomeConfigProps): WorkspaceOptions => ({\n  name: 'home',\n  title: 'Home',\n  basePath: '/home',\n  projectId,\n  dataset,\n  icon: HomeIcon,\n  plugins: [workspaceHome()],\n})\n"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["createIcon(icon)","useMemo(() => createIcon(icon), [icon])","[2, 3, 4, 4]","() => setActiveWorkspace(name)","iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null","[1, 2, 3, 3]","<Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>","title || name","subtitle ? <Text muted>{subtitle}</Text> : null","<Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>","<Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>","<Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>","<Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>","<Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>","[2, 3, 3, 3]","!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null","<Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>","<Grid gridTemplateColumns={5} gap={[2, 3, 4, 4]} paddingY={1}>\n        <Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>\n        <Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>\n        <Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>\n        {/* <Button\n          mode={isFavourite ? 'default' : 'bleed'}\n          tone={isFavourite ? 'primary' : 'default'}\n          icon={StarIcon}\n          title=\"Favorite\"\n          onClick={() => {\n            setIsFavourite(!isFavourite)\n            setFavoriteWorkspace()\n          }}\n        /> */}\n      </Grid>","<Card borderTop={Boolean(index)} tone=\"default\">\n      <Grid gridTemplateColumns={5} gap={[2, 3, 4, 4]} paddingY={1}>\n        <Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>\n        <Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>\n        <Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>\n        {/* <Button\n          mode={isFavourite ? 'default' : 'bleed'}\n          tone={isFavourite ? 'primary' : 'default'}\n          icon={StarIcon}\n          title=\"Favorite\"\n          onClick={() => {\n            setIsFavourite(!isFavourite)\n            setFavoriteWorkspace()\n          }}\n        /> */}\n      </Grid>\n    </Card>","Boolean(index)","_c","useWorkspaces()","(e: React.ChangeEvent<HTMLInputElement>) => {\n      setQuery(e.target.value)\n    }","useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      setQuery(e.target.value)\n    },\n    [setQuery],\n  )","workspaces.filter((workspace) => {\n      return (\n        workspace.name.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.dataset.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.title.toLowerCase().includes(query.toLowerCase())\n      )\n    })","useMemo(() => {\n    return workspaces.filter((workspace) => {\n      return (\n        workspace.name.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.dataset.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.title.toLowerCase().includes(query.toLowerCase())\n      )\n    })\n  }, [workspaces, query])","() => {\n    const handleKeypress = (event: KeyboardEvent) => {\n      // Ignore if search query exists or search input is focused\n      if (query || searchInput.current === document.activeElement) {\n        return\n      }\n\n      const index = parseInt(event.key, 10) - 1\n      if (index >= 0 && index < workspaces.length) {\n        setActiveWorkspace(workspaces[index]!.name)\n      }\n    }\n\n    window.addEventListener('keypress', handleKeypress)\n\n    return () => {\n      window.removeEventListener('keypress', handleKeypress)\n    }\n  }","[query, workspaces, setActiveWorkspace]","workspaces.length","[4, 5, 6, 6]","<Heading>Workspaces</Heading>","[2, 3, 4, 4]","<Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>","<Stack gap={2}>\n                  <Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>\n                  <TextInput ref={searchInput} value={query} onChange={handleQuery} />\n                </Stack>","<Box>\n                  {filteredWorkspaces.map((workspace, index) => (\n                    <WorkspacePreview\n                      key={workspace.name}\n                      workspace={workspace}\n                      index={index}\n                      query={query}\n                    />\n                  ))}\n                </Box>","workspace","index","<TallCard tone=\"transparent\">\n      <Flex direction=\"column\" padding={[4, 5, 6, 6]}>\n        <Container>\n          <Stack gap={4}>\n            <Heading>Workspaces</Heading>\n            <Card padding={[2, 3, 4, 4]} radius={3} shadow={2}>\n              <Stack gap={3}>\n                <Stack gap={2}>\n                  <Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>\n                  <TextInput ref={searchInput} value={query} onChange={handleQuery} />\n                </Stack>\n                <Box>\n                  {filteredWorkspaces.map((workspace, index) => (\n                    <WorkspacePreview\n                      key={workspace.name}\n                      workspace={workspace}\n                      index={index}\n                      query={query}\n                    />\n                  ))}\n                </Box>\n              </Stack>\n            </Card>\n          </Stack>\n        </Container>\n      </Flex>\n    </TallCard>","_c"],"sources":["../src/components/WorkspacePreview.tsx","../src/components/WorkspaceHome.tsx","../src/index.ts"],"sourcesContent":["import {DatabaseIcon} from '@sanity/icons/Database'\nimport {Box, Button, Card, Flex, Grid, Hotkeys, Stack, Text} from '@sanity/ui'\nimport {isValidElement, useMemo} from 'react'\nimport {isValidElementType} from 'react-is'\nimport {useActiveWorkspace, type WorkspaceSummary} from 'sanity'\nimport {styled} from 'styled-components'\n\nconst createIcon = (Icon: React.ComponentType | React.ReactNode) => {\n  if (isValidElementType(Icon)) return <Icon />\n  if (isValidElement(Icon)) return Icon\n  return undefined\n}\n\nconst MediaCard = styled(Card)`\n  width: 35px;\n  height: 35px;\n\n  svg {\n    width: 100%;\n    height: 100%;\n  }\n`\n\nexport type WorkspacePreviewProps = {\n  workspace: WorkspaceSummary\n  index: number\n  query: string\n}\n\nexport default function WorkspacePreview(props: WorkspacePreviewProps): React.JSX.Element {\n  const {workspace, index, query} = props\n  const {icon, title, name, subtitle, dataset} = workspace\n\n  const {setActiveWorkspace} = useActiveWorkspace()\n  const iconComponent = useMemo(() => createIcon(icon), [icon])\n\n  // TODO: Favorites feature\n  // get favorite workspace name from localStorage\n  //   const favoriteWorkspace = localStorage.getItem('favoriteWorkspace')\n  //   save local state to force re-render\n  //   const [isFavourite, setIsFavourite] = React.useState(favoriteWorkspace === name)\n\n  // set favorite workspace name to localStorage\n  //   const setFavoriteWorkspace = useCallback(() => {\n  //     localStorage.setItem('favoriteWorkspace', name)\n  //   }, [name])\n\n  const hotKeyIndex = index + 1 === 10 ? 0 : index + 1\n\n  return (\n    <Card borderTop={Boolean(index)} tone=\"default\">\n      <Grid gridTemplateColumns={5} gap={[2, 3, 4, 4]} paddingY={1}>\n        <Card gridColumnStart={1} gridColumnEnd={4}>\n          <Stack>\n            <Button mode=\"bleed\" tone=\"default\" onClick={() => setActiveWorkspace(name)}>\n              <Flex align=\"center\" gap={[2, 3, 4, 4]}>\n                {iconComponent ? <MediaCard>{createIcon(iconComponent)}</MediaCard> : null}\n                <Box flex={1}>\n                  <Stack gap={[1, 2, 3, 3]}>\n                    <Text size={3} weight=\"semibold\" textOverflow=\"ellipsis\">\n                      {title || name}\n                    </Text>\n                    {subtitle ? <Text muted>{subtitle}</Text> : null}\n                  </Stack>\n                </Box>\n              </Flex>\n            </Button>\n          </Stack>\n        </Card>\n        <Card gridColumnStart={4} gridColumnEnd={5}>\n          <Flex height=\"fill\" align=\"center\" gap={2}>\n            <Text size={1} weight=\"semibold\">\n              <DatabaseIcon />\n            </Text>\n            <Text size={1} weight=\"semibold\" textOverflow=\"ellipsis\">\n              {dataset}\n            </Text>\n          </Flex>\n        </Card>\n        <Card paddingRight={[2, 3, 3, 3]}>\n          <Flex height=\"fill\" align=\"center\" justify=\"flex-end\">\n            {!query && hotKeyIndex < 10 ? (\n              <Hotkeys keys={[String(hotKeyIndex)]} padding={2} />\n            ) : null}\n          </Flex>\n        </Card>\n        {/* <Button\n          mode={isFavourite ? 'default' : 'bleed'}\n          tone={isFavourite ? 'primary' : 'default'}\n          icon={StarIcon}\n          title=\"Favorite\"\n          onClick={() => {\n            setIsFavourite(!isFavourite)\n            setFavoriteWorkspace()\n          }}\n        /> */}\n      </Grid>\n    </Card>\n  )\n}\n","import {Box, Card, Container, Flex, Heading, Stack, Text, TextInput} from '@sanity/ui'\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react'\nimport {useActiveWorkspace, useWorkspaces} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport WorkspacePreview from './WorkspacePreview'\n\nconst TallCard = styled(Card)`\n  min-height: 100%;\n`\n\nexport default function WorkspaceHome(): React.JSX.Element {\n  const [, ...workspaces] = useWorkspaces()\n  const {setActiveWorkspace} = useActiveWorkspace()\n\n  // Handle search query\n  const [query, setQuery] = useState('')\n  const searchInput = useRef(null)\n  const handleQuery = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      setQuery(e.target.value)\n    },\n    [setQuery],\n  )\n\n  // filter workspaces if name, dataset or title matches query\n  const filteredWorkspaces = useMemo(() => {\n    return workspaces.filter((workspace) => {\n      return (\n        workspace.name.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.dataset.toLowerCase().includes(query.toLowerCase()) ||\n        workspace.title.toLowerCase().includes(query.toLowerCase())\n      )\n    })\n  }, [workspaces, query])\n\n  // Listen to keypress of workspace index\n  useEffect(() => {\n    const handleKeypress = (event: KeyboardEvent) => {\n      // Ignore if search query exists or search input is focused\n      if (query || searchInput.current === document.activeElement) {\n        return\n      }\n\n      const index = parseInt(event.key, 10) - 1\n      if (index >= 0 && index < workspaces.length) {\n        setActiveWorkspace(workspaces[index]!.name)\n      }\n    }\n\n    window.addEventListener('keypress', handleKeypress)\n\n    return () => {\n      window.removeEventListener('keypress', handleKeypress)\n    }\n  }, [query, workspaces, setActiveWorkspace])\n\n  return (\n    <TallCard tone=\"transparent\">\n      <Flex direction=\"column\" padding={[4, 5, 6, 6]}>\n        <Container>\n          <Stack gap={4}>\n            <Heading>Workspaces</Heading>\n            <Card padding={[2, 3, 4, 4]} radius={3} shadow={2}>\n              <Stack gap={3}>\n                <Stack gap={2}>\n                  <Text size={1} weight=\"semibold\">\n                    Search\n                  </Text>\n                  <TextInput ref={searchInput} value={query} onChange={handleQuery} />\n                </Stack>\n                <Box>\n                  {filteredWorkspaces.map((workspace, index) => (\n                    <WorkspacePreview\n                      key={workspace.name}\n                      workspace={workspace}\n                      index={index}\n                      query={query}\n                    />\n                  ))}\n                </Box>\n              </Stack>\n            </Card>\n          </Stack>\n        </Container>\n      </Flex>\n    </TallCard>\n  )\n}\n","import '@sanity/ui/styles.css'\nimport {HomeIcon} from '@sanity/icons/Home'\nimport {definePlugin, type Plugin, type WorkspaceOptions} from 'sanity'\n\nimport WorkspaceHome from './components/WorkspaceHome'\n\nexport const workspaceHome: Plugin = definePlugin(() => {\n  return {\n    name: 'sanity-plugin-workspace-home',\n    tools: [\n      {\n        title: 'Workspace Home',\n        name: 'workspace-home',\n        icon: HomeIcon,\n        component: WorkspaceHome,\n      },\n    ],\n  }\n})\n\ntype WorkspaceHomeConfigProps = {\n  projectId: string\n  dataset: string\n}\n\nexport const workspaceHomeConfig = ({\n  projectId,\n  dataset,\n}: WorkspaceHomeConfigProps): WorkspaceOptions => ({\n  name: 'home',\n  title: 'Home',\n  basePath: '/home',\n  projectId,\n  dataset,\n  icon: HomeIcon,\n  plugins: [workspaceHome()],\n})\n"],"mappings":"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"}
\ No newline at end of file