mirror of
https://github.com/penxio/penx.git
synced 2026-01-14 16:07:58 -05:00
feat: can render command list
This commit is contained in:
@@ -23,8 +23,6 @@ export const EditorApp: FC<PropsWithChildren> = ({ children }) => {
|
||||
})
|
||||
}, [])
|
||||
|
||||
console.log('isLoaded:', isLoaded)
|
||||
|
||||
if (!isLoaded) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ import {
|
||||
PopoverTrigger,
|
||||
} from 'uikit'
|
||||
import { CatalogueNodeType } from '@penx/catalogue'
|
||||
import { useCatalogue, useSpaces } from '@penx/hooks'
|
||||
import { db } from '@penx/local-db'
|
||||
import { useCatalogue } from '@penx/hooks'
|
||||
|
||||
const initialValue = [
|
||||
{
|
||||
|
||||
53
packages/app/src/Palette/CommandList.tsx
Normal file
53
packages/app/src/Palette/CommandList.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Box, styled } from '@fower/react'
|
||||
import { Command } from '@penx/cmdk'
|
||||
import { useCommands } from '@penx/hooks'
|
||||
|
||||
const CommandItem = styled(Command.Item)
|
||||
|
||||
interface Props {
|
||||
q: string
|
||||
close: () => void
|
||||
}
|
||||
|
||||
export function CommandList({ q, close }: Props) {
|
||||
const { commands } = useCommands()
|
||||
const search = q.replace(/^>(\s+)?/, '').toLowerCase()
|
||||
|
||||
const filteredItems = commands.filter((i) => {
|
||||
if (!search) return true
|
||||
return (
|
||||
i.title.toLowerCase().includes(search) ||
|
||||
i.id.toLowerCase().includes(search)
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
{!filteredItems.length && (
|
||||
<Command.Empty>No results found.</Command.Empty>
|
||||
)}
|
||||
|
||||
{filteredItems.map((item, i) => (
|
||||
<CommandItem
|
||||
key={item.id}
|
||||
h10
|
||||
cursorPointer
|
||||
toCenterY
|
||||
px2
|
||||
transitionCommon
|
||||
roundedLG
|
||||
value={item.id}
|
||||
onSelect={() => {
|
||||
close()
|
||||
item.handler()
|
||||
}}
|
||||
onClick={() => {
|
||||
item.handler()
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</CommandItem>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
47
packages/app/src/Palette/DocList.tsx
Normal file
47
packages/app/src/Palette/DocList.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { styled } from '@fower/react'
|
||||
import { Command } from '@penx/cmdk'
|
||||
import { useCatalogue } from '@penx/hooks'
|
||||
|
||||
const CommandItem = styled(Command.Item)
|
||||
|
||||
interface Props {
|
||||
q: string
|
||||
close: () => void
|
||||
}
|
||||
|
||||
export function DocList({ q, close }: Props) {
|
||||
const catalogue = useCatalogue()
|
||||
const filteredItems = catalogue.docNodes.filter((i) =>
|
||||
i.name.toLowerCase().includes(q.toLowerCase()),
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
{!filteredItems.length && (
|
||||
<Command.Empty>No results found.</Command.Empty>
|
||||
)}
|
||||
|
||||
{filteredItems.map((node) => (
|
||||
<CommandItem
|
||||
key={node.id}
|
||||
h10
|
||||
cursorPointer
|
||||
toCenterY
|
||||
px2
|
||||
transitionCommon
|
||||
roundedLG
|
||||
value={node.id}
|
||||
onSelect={() => {
|
||||
close()
|
||||
catalogue.selectNode(node)
|
||||
}}
|
||||
onClick={() => {
|
||||
catalogue.selectNode(node)
|
||||
}}
|
||||
>
|
||||
{node.name}
|
||||
</CommandItem>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -2,15 +2,18 @@ import { useEffect, useState } from 'react'
|
||||
import { Box, styled } from '@fower/react'
|
||||
import { Command } from '@penx/cmdk'
|
||||
import { useCatalogue } from '@penx/hooks'
|
||||
import { CommandList } from './CommandList'
|
||||
import { DocList } from './DocList'
|
||||
|
||||
const CommandDialog = styled(Command.Dialog)
|
||||
const CommandInput = styled(Command.Input)
|
||||
const CommandList = styled(Command.List)
|
||||
const CommandItem = styled(Command.Item)
|
||||
const StyledCommandList = styled(Command.List)
|
||||
const StyledCommandItem = styled(Command.Item)
|
||||
|
||||
export function CommandPanel() {
|
||||
const [open, setOpen] = useState(false)
|
||||
const [search, setSearch] = useState('')
|
||||
|
||||
const catalogue = useCatalogue()
|
||||
const filteredItems = catalogue.docNodes.filter((i) =>
|
||||
i.name.toLowerCase().includes(search.toLowerCase()),
|
||||
@@ -29,6 +32,9 @@ export function CommandPanel() {
|
||||
return () => document.removeEventListener('keydown', down)
|
||||
}, [])
|
||||
|
||||
const close = () => setOpen(false)
|
||||
const isCommand = search.startsWith('>')
|
||||
|
||||
return (
|
||||
<CommandDialog
|
||||
shadow="0 16px 70px rgba(0,0,0,.2)"
|
||||
@@ -84,7 +90,7 @@ export function CommandPanel() {
|
||||
}}
|
||||
/>
|
||||
|
||||
<CommandList
|
||||
<StyledCommandList
|
||||
maxH-400
|
||||
px2
|
||||
overflowAuto
|
||||
@@ -95,33 +101,10 @@ export function CommandPanel() {
|
||||
overscrollBehavior: 'contain',
|
||||
}}
|
||||
>
|
||||
{!filteredItems.length && (
|
||||
<Command.Empty>No results found.</Command.Empty>
|
||||
)}
|
||||
{!isCommand && <DocList q={search} close={close} />}
|
||||
|
||||
{filteredItems.map((node) => (
|
||||
<CommandItem
|
||||
key={node.id}
|
||||
h10
|
||||
cursorPointer
|
||||
toCenterY
|
||||
px2
|
||||
transitionCommon
|
||||
roundedLG
|
||||
value={node.id}
|
||||
onSelect={() => {
|
||||
setOpen(false)
|
||||
catalogue.selectNode(node)
|
||||
}}
|
||||
onClick={() => {
|
||||
catalogue.selectNode(node)
|
||||
}}
|
||||
>
|
||||
{node.name}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandList>
|
||||
<Box>GOGO</Box>
|
||||
{isCommand && <CommandList q={search} close={close} />}
|
||||
</StyledCommandList>
|
||||
</CommandDialog>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -82,9 +82,6 @@ export class SyncService {
|
||||
const changedIds = s.space.getChangedDocIds()
|
||||
|
||||
const docs = await db.queryDocByIds(changedIds)
|
||||
console.log('docs:', docs)
|
||||
|
||||
console.log('docs:', docs)
|
||||
|
||||
s.docs = docs.map((doc) => new Doc(doc))
|
||||
|
||||
|
||||
@@ -7,3 +7,4 @@ export * from './useHover'
|
||||
export * from './useCreateSpaceForm'
|
||||
export * from './useSyncStatus'
|
||||
export * from './useWorkers'
|
||||
export * from './useCommands'
|
||||
|
||||
7
packages/hooks/src/useCommands.ts
Normal file
7
packages/hooks/src/useCommands.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useAtom } from 'jotai'
|
||||
import { commandsAtom } from '@penx/store'
|
||||
|
||||
export function useCommands() {
|
||||
const [commands] = useAtom(commandsAtom)
|
||||
return { commands }
|
||||
}
|
||||
@@ -4,7 +4,8 @@ import { IDoc, ISpace } from '@penx/local-db'
|
||||
|
||||
export type Command = {
|
||||
id: string
|
||||
name: string
|
||||
title: string
|
||||
pluginId?: string
|
||||
handler: () => void
|
||||
}
|
||||
export type PluginStore = Record<
|
||||
@@ -26,8 +27,17 @@ export const syncStatusAtom = atom<SyncStatus>(SyncStatus.NORMAL)
|
||||
export const commandsAtom = atom<Command[]>([
|
||||
{
|
||||
id: 'foo',
|
||||
name: 'foo',
|
||||
handler: () => {},
|
||||
title: 'foo',
|
||||
handler: () => {
|
||||
console.log('fooo')
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'bar',
|
||||
title: 'bar',
|
||||
handler: () => {
|
||||
console.log('bar')
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user