@veiag/payload-cmdk 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,11 +7,17 @@ A powerful command menu plugin for [Payload CMS](https://payloadcms.com) that en
7
7
  ## Features
8
8
 
9
9
  ✨ **Quick Search** - Instantly search across all collections and globals
10
+
10
11
  ⌨️ **Keyboard Shortcuts** - Fully customizable keyboard shortcuts powered by [react-hotkeys-hook](https://react-hotkeys-hook.vercel.app/docs/intro)
12
+
11
13
  🔍 **Collection Submenu** - Search within collection documents by their title field
14
+
12
15
  🎨 **Custom Icons** - Use any [Lucide icon](https://lucide.dev/icons) for collections and globals
16
+
13
17
  🎯 **Custom Items** - Add custom actions and menu groups
18
+
14
19
  🌍 **i18n Support** - Built-in English and Ukrainian translations, easily add your own
20
+
15
21
  🖥️ **Cross-platform** - Optimized shortcuts for both macOS and Windows/Linux
16
22
 
17
23
 
@@ -76,22 +82,22 @@ export default buildConfig({
76
82
  enabled: true, // Default
77
83
  shortcut: 'shift+enter', // 'shift+enter' | 'enter'
78
84
  icons: {
79
- posts: 'file-text',
80
- users: 'user',
85
+ posts: 'FileText',
86
+ users: 'User',
81
87
  },
82
88
  },
83
89
 
84
90
  // Custom icons for collections and globals
85
91
  icons: {
86
92
  collections: {
87
- posts: 'file-text',
88
- pages: 'file',
89
- media: 'image',
90
- users: 'users',
93
+ posts: 'FileText',
94
+ pages: 'File',
95
+ media: 'Image',
96
+ users: 'Users',
91
97
  },
92
98
  globals: {
93
- settings: 'settings',
94
- navigation: 'menu',
99
+ settings: 'Settings',
100
+ navigation: 'Menu',
95
101
  },
96
102
  },
97
103
 
@@ -108,7 +114,7 @@ export default buildConfig({
108
114
  type: 'item',
109
115
  slug: 'view-site',
110
116
  label: 'View Site',
111
- icon: 'external-link',
117
+ icon: 'ExternalLink',
112
118
  action: {
113
119
  type: 'link',
114
120
  href: 'https://your-site.com',
@@ -118,7 +124,7 @@ export default buildConfig({
118
124
  type: 'item',
119
125
  slug: 'clear-cache',
120
126
  label: 'Clear Cache',
121
- icon: 'trash-2',
127
+ icon: 'Trash2',
122
128
  action: {
123
129
  type: 'api',
124
130
  method: 'POST',
@@ -235,8 +241,8 @@ submenu: {
235
241
  enabled: true,
236
242
  shortcut: 'enter',
237
243
  icons: {
238
- posts: 'file-text',
239
- products: 'shopping-cart',
244
+ posts: 'FileText',
245
+ products: 'ShoppingCart',
240
246
  }
241
247
  }
242
248
  ```
@@ -268,16 +274,16 @@ Customize icons for collections and globals using [Lucide icon names](https://lu
268
274
  ```typescript
269
275
  icons: {
270
276
  collections: {
271
- posts: 'file-text',
272
- pages: 'file',
273
- media: 'image',
274
- users: 'users',
275
- categories: 'folder',
277
+ posts: 'FileText',
278
+ pages: 'File',
279
+ media: 'Image',
280
+ users: 'Users',
281
+ categories: 'Folder',
276
282
  },
277
283
  globals: {
278
- settings: 'settings',
279
- navigation: 'menu',
280
- footer: 'layout',
284
+ settings: 'Settings',
285
+ navigation: 'Menu',
286
+ footer: 'Layout',
281
287
  }
282
288
  }
283
289
  ```
@@ -300,7 +306,7 @@ Add custom menu items and groups to the command menu.
300
306
  type: 'item',
301
307
  slug: 'unique-slug',
302
308
  label: 'Item Label', // Can be localized
303
- icon: 'lucide-icon-name', // Optional, from lucide.dev/icons
309
+ icon: 'LucideIconName', // Optional, from lucide.dev/icons
304
310
  action: {
305
311
  type: 'link' | 'api',
306
312
  href: '/path/or/url',
@@ -340,7 +346,7 @@ customItems: [
340
346
  en: 'View Site',
341
347
  uk: 'Переглянути сайт',
342
348
  },
343
- icon: 'external-link',
349
+ icon: 'ExternalLink',
344
350
  action: {
345
351
  type: 'link',
346
352
  href: 'https://your-site.com',
@@ -350,7 +356,7 @@ customItems: [
350
356
  type: 'item',
351
357
  slug: 'regenerate',
352
358
  label: 'Regenerate Cache',
353
- icon: 'refresh-cw',
359
+ icon: 'RefreshCw',
354
360
  action: {
355
361
  type: 'api',
356
362
  method: 'POST',
@@ -517,7 +523,7 @@ export default buildConfig({
517
523
  type: 'item',
518
524
  slug: 'documentation',
519
525
  label: 'View Documentation',
520
- icon: 'book-open',
526
+ icon: 'BookOpen',
521
527
  action: {
522
528
  type: 'link',
523
529
  href: 'https://docs.your-site.com',
@@ -537,28 +543,28 @@ export default buildConfig({
537
543
  payloadCmdk({
538
544
  icons: {
539
545
  collections: {
540
- posts: 'newspaper',
541
- pages: 'file-text',
542
- media: 'image',
543
- categories: 'folder-tree',
544
- tags: 'tag',
545
- users: 'user-circle',
546
- comments: 'message-circle',
546
+ posts: 'Newspaper',
547
+ pages: 'FileText',
548
+ media: 'Image',
549
+ categories: 'FolderTree',
550
+ tags: 'Tag',
551
+ users: 'UserCircle',
552
+ comments: 'MessageCircle',
547
553
  },
548
554
  globals: {
549
- header: 'layout-template',
550
- footer: 'layout',
551
- settings: 'settings-2',
552
- navigation: 'navigation',
553
- seo: 'search',
555
+ header: 'LayoutTemplate',
556
+ footer: 'Layout',
557
+ settings: 'Settings',
558
+ navigation: 'Menu',
559
+ seo: 'Search',
554
560
  },
555
561
  },
556
562
  submenu: {
557
563
  enabled: true,
558
564
  icons: {
559
- posts: 'file-text',
560
- pages: 'file',
561
- media: 'image',
565
+ posts: 'FileText',
566
+ pages: 'File',
567
+ media: 'Image',
562
568
  },
563
569
  },
564
570
  }),
@@ -566,6 +572,9 @@ export default buildConfig({
566
572
  })
567
573
  ```
568
574
 
575
+ ## Troubleshooting
576
+ - `Objects are not valid as a React child` error: Ensure your `admin.useAsTitle` field is a string and not an object. Currently, plugin doesn't have any safeguards for non-string title fields.
577
+
569
578
  ## Contributing
570
579
 
571
580
  Contributions are welcome! Please feel free to submit a Pull Request.
@@ -586,6 +595,7 @@ MIT © [VeiaG](https://github.com/VeiaG)
586
595
 
587
596
  ## Links
588
597
 
598
+ - [cmdk Component](https://cmdk.paco.me/)
589
599
  - [GitHub Repository](https://github.com/VeiaG/payload-cmdk/tree/main)
590
600
  - [Payload CMS](https://payloadcms.com)
591
601
  - [Lucide Icons](https://lucide.dev/icons)
@@ -3,12 +3,12 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import './modal.scss';
4
4
  import { Modal, useConfig, useModal, useTranslation } from '@payloadcms/ui';
5
5
  import { ArrowBigUp, ChevronLeft, Command as CommandIcon, Option } from 'lucide-react';
6
- import { DynamicIcon } from 'lucide-react/dynamic';
7
6
  import { useRouter } from 'next/navigation';
8
7
  import { createContext, Fragment, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
9
8
  import { useHotkeys } from 'react-hotkeys-hook';
10
9
  import { createDefaultGroups } from '../utils/index';
11
10
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from './cmdk/index';
11
+ import { LucideIconDynamic } from './LucideIcon';
12
12
  const MODAL_SLUG = 'command-menu';
13
13
  const CommandMenuContext = /*#__PURE__*/ createContext({
14
14
  closeMenu: ()=>{},
@@ -320,7 +320,7 @@ const CommandMenuComponent = ({ pluginConfig })=>{
320
320
  onSelect: ()=>handleSelect(item),
321
321
  value: item.slug,
322
322
  children: [
323
- isDynamicIcon ? /*#__PURE__*/ _jsx(DynamicIcon, {
323
+ isDynamicIcon ? /*#__PURE__*/ _jsx(LucideIconDynamic, {
324
324
  className: "command__item-icon",
325
325
  name: item.icon
326
326
  }) : IconComponent && /*#__PURE__*/ _jsx(IconComponent, {
@@ -354,7 +354,7 @@ const CommandMenuComponent = ({ pluginConfig })=>{
354
354
  onSelect: ()=>handleSelect(item),
355
355
  value: item.slug,
356
356
  children: [
357
- isDynamicIcon ? /*#__PURE__*/ _jsx(DynamicIcon, {
357
+ isDynamicIcon ? /*#__PURE__*/ _jsx(LucideIconDynamic, {
358
358
  className: "command__item-icon",
359
359
  name: item.icon
360
360
  }) : IconComponent && /*#__PURE__*/ _jsx(IconComponent, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/CommandMenuContext.tsx"],"sourcesContent":["'use client'\nimport type { LucideIcon } from 'lucide-react'\nimport type { IconName } from 'lucide-react/dynamic'\nimport type { CustomTranslationsKeys, CustomTranslationsObject } from 'src/translations/index'\n\nimport './modal.scss'\n\nimport type {\n CommandMenuContextProps,\n CommandMenuGroup,\n CommandMenuItem,\n CommandMenuPage,\n GenericCollectionDocument,\n PluginCommandMenuConfig,\n} from 'src/types'\n\nimport { Modal, useConfig, useModal, useTranslation } from '@payloadcms/ui'\nimport { ArrowBigUp, ChevronLeft, Command as CommandIcon, Option } from 'lucide-react'\nimport { DynamicIcon } from 'lucide-react/dynamic'\nimport { useRouter } from 'next/navigation'\nimport {\n createContext,\n Fragment,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { useHotkeys } from 'react-hotkeys-hook'\n\nimport { createDefaultGroups } from '../utils/index'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n} from './cmdk/index'\n\nconst MODAL_SLUG = 'command-menu'\n\ninterface CommandMenuContextType {\n closeMenu: () => void\n currentPage: CommandMenuPage\n groups: CommandMenuGroup[]\n isOpen: boolean\n items: CommandMenuItem[]\n openMenu: () => void\n setPage: (page: CommandMenuPage) => void\n toggleMenu: () => void\n}\n\nconst CommandMenuContext = createContext<CommandMenuContextType>({\n closeMenu: () => {},\n currentPage: 'main',\n groups: [],\n isOpen: false,\n items: [],\n openMenu: () => {},\n setPage: () => {},\n toggleMenu: () => {},\n})\n\nexport const useCommandMenu = () => {\n const context = useContext(CommandMenuContext)\n return context\n}\n\nconst ITEM_SELECTOR = `[cmdk-item=\"\"]`\n\nfunction getSelectedElement(containerRef: React.RefObject<HTMLElement | null>) {\n return containerRef.current?.querySelector(`${ITEM_SELECTOR}[aria-selected=\"true\"]`)\n}\n\nconst CommandMenuComponent: React.FC<{\n pluginConfig: PluginCommandMenuConfig\n}> = ({ pluginConfig }) => {\n const [search, setSearch] = useState('')\n const [submenuItems, setSubmenuItems] = useState<CommandMenuItem[]>([])\n const [isLoadingSubmenu, setIsLoadingSubmenu] = useState(false)\n const [isMac, setIsMac] = useState(false)\n\n const commandListRef = useRef<HTMLDivElement>(null)\n\n const { closeMenu, currentPage, groups, items, setPage } = useCommandMenu()\n const router = useRouter()\n const { t } = useTranslation<CustomTranslationsObject, CustomTranslationsKeys>()\n\n useEffect(() => {\n setIsMac(/Mac|iPhone|iPod|iPad/i.test(navigator.platform))\n }, [])\n\n const submenuEnabled = pluginConfig?.submenu?.enabled !== false\n const submenuShortcut = pluginConfig?.submenu?.shortcut || 'shift+enter'\n const blurBg = pluginConfig?.blurBg !== false\n\n const formatShortcutKey = (key: string): React.ReactNode => {\n // Handle compound shortcuts like \"Shift + Enter\"\n const parts = key.split('+').map((part) => part.trim())\n const elements = parts.map((part, index) => {\n const lowerPart = part.toLowerCase()\n let content: React.ReactNode\n\n if (lowerPart === 'ctrl' || lowerPart === 'cmd') {\n content = isMac ? <CommandIcon size={12} /> : 'Ctrl'\n } else if (lowerPart === 'meta') {\n content = isMac ? <CommandIcon size={12} /> : 'Ctrl'\n } else if (lowerPart === 'shift') {\n content = isMac ? <ArrowBigUp size={12} /> : 'Shift'\n } else if (lowerPart === 'alt') {\n content = isMac ? <Option size={12} /> : 'Alt'\n } else {\n content = part\n }\n\n return (\n <Fragment key={index}>\n {content}\n {!isMac && index < parts.length - 1 && ' + '}\n </Fragment>\n )\n })\n\n return <>{elements}</>\n }\n\n // Debounced search for submenu\n useEffect(() => {\n if (currentPage === 'main') {\n return\n }\n\n const fetchDocuments = async () => {\n if (currentPage.type !== 'collection-search') {\n return\n }\n\n setIsLoadingSubmenu(true)\n try {\n const searchParam = search\n ? `&where[${currentPage.useAsTitle}][like]=${encodeURIComponent(search)}`\n : ''\n const response = await fetch(\n `/api/${currentPage.slug}?limit=10${searchParam}&select[${currentPage.useAsTitle}]=true`,\n )\n const data = await response.json()\n\n if (data.docs && Array.isArray(data.docs)) {\n const docs: CommandMenuItem[] = data.docs.map((doc: GenericCollectionDocument) => ({\n slug: `${currentPage.slug}-${doc.id}`,\n type: 'custom' as const,\n action: {\n type: 'link',\n href: `/admin/collections/${currentPage.slug}/${doc.id}`,\n },\n icon: pluginConfig?.submenu?.icons?.[currentPage.slug] ?? undefined,\n label: doc[currentPage.useAsTitle] || doc.id,\n }))\n setSubmenuItems(docs)\n }\n } catch {\n setSubmenuItems([])\n } finally {\n setIsLoadingSubmenu(false)\n }\n }\n\n const timeoutId = setTimeout(fetchDocuments, 300)\n return () => clearTimeout(timeoutId)\n }, [search, currentPage, pluginConfig?.submenu?.icons])\n\n const handleBack = useCallback(() => {\n setPage('main')\n setSearch('')\n setSubmenuItems([])\n }, [setPage])\n\n const executeItemAction = useCallback(\n async (item: CommandMenuItem) => {\n // Execute the item's action\n switch (item.action.type) {\n case 'api':\n await fetch(item.action.href, {\n body: item.action.body ? JSON.stringify(item.action.body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n },\n method: item.action.method || 'GET',\n })\n break\n case 'link':\n router.push(item.action.href)\n break\n default:\n break\n }\n closeMenu()\n setSearch('')\n setPage('main')\n },\n [router, closeMenu, setPage],\n )\n\n const openSubmenu = useCallback(\n (item: CommandMenuItem) => {\n setPage({\n slug: item.slug,\n type: 'collection-search',\n label: item.label,\n useAsTitle: item.useAsTitle || 'id',\n useAsTitleLabel: item.useAsTitleLabel || item.useAsTitle || 'id',\n })\n setSearch('')\n //set isLoadingSubmenu to true to show loading state while fetching\n setIsLoadingSubmenu(true)\n setSubmenuItems([])\n },\n [setPage],\n )\n\n const handleSelect = useCallback(\n async (item: CommandMenuItem) => {\n await executeItemAction(item)\n },\n [executeItemAction],\n )\n\n // Handle keyboard events for navigation and back\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // ESC key for back navigation in submenu\n if (e.key === 'Escape' && currentPage !== 'main') {\n e.preventDefault()\n e.stopPropagation()\n handleBack()\n return\n }\n\n // Enter/Shift+Enter handling for collection submenu\n if (e.key === 'Enter' && currentPage === 'main') {\n const selectedElement = getSelectedElement(commandListRef)\n const itemType = selectedElement?.getAttribute('data-item-type')\n const itemSlug = selectedElement?.getAttribute('data-value')\n\n if (submenuEnabled && itemType === 'collection' && itemSlug) {\n const isShiftPressed = e.shiftKey\n const shouldOpenSubmenu =\n (submenuShortcut === 'shift+enter' && isShiftPressed) ||\n (submenuShortcut === 'enter' && !isShiftPressed)\n\n if (shouldOpenSubmenu) {\n e.preventDefault()\n e.stopPropagation()\n\n // Find the item in groups\n const item = groups.flatMap((g) => g.items).find((i) => i.slug === itemSlug)\n if (item) {\n openSubmenu(item)\n }\n return\n }\n }\n }\n }\n\n document.addEventListener('keydown', handleKeyDown, true)\n return () => document.removeEventListener('keydown', handleKeyDown, true)\n }, [currentPage, handleBack, submenuEnabled, submenuShortcut, openSubmenu, groups])\n\n const placeholder =\n currentPage === 'main'\n ? t('cmdkPlugin:search')\n : t('general:searchBy', {\n label: currentPage.useAsTitleLabel,\n })\n\n const shouldDisableFilter = currentPage !== 'main'\n\n // Static footer shortcuts based on current page\n const footerShortcuts = currentPage === 'main' && submenuEnabled && submenuShortcut === 'shift+enter'\n ? [\n { key: 'Enter', label: t('cmdkPlugin:navigate') },\n { key: 'Shift + Enter', label: t('cmdkPlugin:searchInCollection') },\n ]\n : currentPage === 'main' && submenuEnabled && submenuShortcut === 'enter'\n ? [\n { key: 'Enter', label: t('cmdkPlugin:searchInCollection') },\n { key: 'Shift + Enter', label: t('cmdkPlugin:navigate') },\n ]\n : currentPage === 'main'\n ? [{ key: 'Enter', label: t('cmdkPlugin:navigate') }]\n : [{ key: 'Enter', label: t('cmdkPlugin:open') }]\n\n const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Close modal only if clicking the backdrop (not the command itself)\n if (e.target === e.currentTarget) {\n closeMenu()\n }\n }\n\n return (\n <Modal slug={MODAL_SLUG}>\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}\n <div\n className={`command-modal ${blurBg ? 'command-modal--blur' : ''}`}\n onClick={handleBackdropClick}\n >\n <Command label=\"Command Menu\" shouldFilter={!shouldDisableFilter}>\n {/* Header for submenu navigation */}\n {currentPage !== 'main' && (\n <div className=\"command__header\">\n <button className=\"command__back-button\" onClick={handleBack} type=\"button\">\n <ChevronLeft size={16} />\n </button>\n <span className=\"command__header-label\">\n {t('cmdkPlugin:searchIn', { label: currentPage.label })}\n </span>\n </div>\n )}\n\n <CommandInput onValueChange={setSearch} placeholder={placeholder} value={search} />\n <CommandList ref={commandListRef}>\n <CommandEmpty>\n {isLoadingSubmenu ? t('cmdkPlugin:loading') : t('cmdkPlugin:noResults')}\n </CommandEmpty>\n\n {/* Main page view */}\n {currentPage === 'main' &&\n groups.map((group, index) => {\n if (group.items.length === 0) {\n return null\n }\n\n let titleName = group.title\n if (group.title === 'Collections') {\n titleName = t('general:collections')\n }\n if (group.title === 'Globals') {\n titleName = t('general:globals')\n }\n\n const isRenderSeparator = !(index === groups.length - 1 && items.length === 0)\n return (\n <Fragment key={group.title}>\n <CommandGroup heading={titleName}>\n {group.items.map((item) => {\n const isDynamicIcon = typeof item.icon === 'string'\n const IconComponent = isDynamicIcon ? null : (item.icon as LucideIcon)\n return (\n <CommandItem\n data-action-type={item.action.type}\n data-item-type={item.type}\n key={item.slug}\n keywords={[group.title]}\n onSelect={() => handleSelect(item)}\n value={item.slug}\n >\n {isDynamicIcon ? (\n <DynamicIcon\n className=\"command__item-icon\"\n name={item.icon as IconName}\n />\n ) : (\n IconComponent && <IconComponent className=\"command__item-icon\" />\n )}\n {item.label}\n {submenuEnabled && item.type === 'collection' && (\n <CommandShortcut>›</CommandShortcut>\n )}\n </CommandItem>\n )\n })}\n </CommandGroup>\n {isRenderSeparator && <CommandSeparator />}\n </Fragment>\n )\n })}\n\n {/* Stray items on main page */}\n {currentPage === 'main' &&\n items?.map((item) => (\n <CommandItem\n data-action-type={item.action.type}\n data-item-type={item.type}\n key={item.slug}\n onSelect={() => handleSelect(item)}\n value={item.slug}\n >\n {item.label}\n </CommandItem>\n ))}\n\n {/* Submenu page view */}\n {currentPage !== 'main' &&\n submenuItems.map((item) => {\n const isDynamicIcon = typeof item.icon === 'string'\n const IconComponent = isDynamicIcon ? null : (item.icon as LucideIcon)\n return (\n <CommandItem\n data-action-type={item.action.type}\n data-item-type={item.type}\n key={item.slug}\n onSelect={() => handleSelect(item)}\n value={item.slug}\n >\n {isDynamicIcon ? (\n <DynamicIcon className=\"command__item-icon\" name={item.icon as IconName} />\n ) : (\n IconComponent && <IconComponent className=\"command__item-icon\" />\n )}\n {item.label}\n </CommandItem>\n )\n })}\n </CommandList>\n\n {/* Footer with static shortcuts */}\n {footerShortcuts && footerShortcuts.length > 0 && (\n <div className=\"command__footer\">\n {footerShortcuts.map((shortcut, index) => (\n <span key={index}>\n <kbd>{formatShortcutKey(shortcut.key)}</kbd> {shortcut.label}\n </span>\n ))}\n </div>\n )}\n </Command>\n </div>\n </Modal>\n )\n}\n\nconst MemoizedCommandMenuComponent = memo(CommandMenuComponent)\n\nexport const CommandMenuProvider: React.FC<CommandMenuContextProps> = ({\n children,\n pluginConfig,\n}) => {\n const { closeModal, isModalOpen, openModal, toggleModal } = useModal()\n const [currentPage, setCurrentPage] = useState<CommandMenuPage>('main')\n\n useHotkeys(\n pluginConfig.shortcut || ['meta+k', 'ctrl+k'],\n (event) => {\n event.preventDefault()\n event.stopPropagation()\n toggleModal(MODAL_SLUG)\n },\n [toggleModal],\n )\n const { config } = useConfig()\n const { i18n } = useTranslation()\n const currentLang = i18n.language\n const { groups, items } = useMemo(() => {\n return createDefaultGroups(config, currentLang, pluginConfig)\n }, [config, currentLang, pluginConfig])\n\n return (\n <CommandMenuContext.Provider\n value={{\n closeMenu: () => closeModal(MODAL_SLUG),\n currentPage,\n groups,\n isOpen: isModalOpen(MODAL_SLUG),\n items,\n openMenu: () => openModal(MODAL_SLUG),\n setPage: setCurrentPage,\n toggleMenu: () => toggleModal(MODAL_SLUG),\n }}\n >\n {children}\n <MemoizedCommandMenuComponent pluginConfig={pluginConfig} />\n </CommandMenuContext.Provider>\n )\n}\n"],"names":["Modal","useConfig","useModal","useTranslation","ArrowBigUp","ChevronLeft","Command","CommandIcon","Option","DynamicIcon","useRouter","createContext","Fragment","memo","useCallback","useContext","useEffect","useMemo","useRef","useState","useHotkeys","createDefaultGroups","CommandEmpty","CommandGroup","CommandInput","CommandItem","CommandList","CommandSeparator","CommandShortcut","MODAL_SLUG","CommandMenuContext","closeMenu","currentPage","groups","isOpen","items","openMenu","setPage","toggleMenu","useCommandMenu","context","ITEM_SELECTOR","getSelectedElement","containerRef","current","querySelector","CommandMenuComponent","pluginConfig","search","setSearch","submenuItems","setSubmenuItems","isLoadingSubmenu","setIsLoadingSubmenu","isMac","setIsMac","commandListRef","router","t","test","navigator","platform","submenuEnabled","submenu","enabled","submenuShortcut","shortcut","blurBg","formatShortcutKey","key","parts","split","map","part","trim","elements","index","lowerPart","toLowerCase","content","size","length","fetchDocuments","type","searchParam","useAsTitle","encodeURIComponent","response","fetch","slug","data","json","docs","Array","isArray","doc","id","action","href","icon","icons","undefined","label","timeoutId","setTimeout","clearTimeout","handleBack","executeItemAction","item","body","JSON","stringify","headers","method","push","openSubmenu","useAsTitleLabel","handleSelect","handleKeyDown","e","preventDefault","stopPropagation","selectedElement","itemType","getAttribute","itemSlug","isShiftPressed","shiftKey","shouldOpenSubmenu","flatMap","g","find","i","document","addEventListener","removeEventListener","placeholder","shouldDisableFilter","footerShortcuts","handleBackdropClick","target","currentTarget","div","className","onClick","shouldFilter","button","span","onValueChange","value","ref","group","titleName","title","isRenderSeparator","heading","isDynamicIcon","IconComponent","data-action-type","data-item-type","keywords","onSelect","name","kbd","MemoizedCommandMenuComponent","CommandMenuProvider","children","closeModal","isModalOpen","openModal","toggleModal","setCurrentPage","event","config","i18n","currentLang","language","Provider"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/components/CommandMenuContext.tsx"],"sourcesContent":["'use client'\nimport type { LucideIcon } from 'lucide-react'\nimport type { CustomTranslationsKeys, CustomTranslationsObject } from 'src/translations/index'\n\nimport './modal.scss'\n\nimport type {\n CommandMenuContextProps,\n CommandMenuGroup,\n CommandMenuItem,\n CommandMenuPage,\n GenericCollectionDocument,\n IconName,\n PluginCommandMenuConfig,\n} from 'src/types'\n\nimport { Modal, useConfig, useModal, useTranslation } from '@payloadcms/ui'\nimport { ArrowBigUp, ChevronLeft, Command as CommandIcon, Option } from 'lucide-react'\nimport { useRouter } from 'next/navigation'\nimport {\n createContext,\n Fragment,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { useHotkeys } from 'react-hotkeys-hook'\n\nimport { createDefaultGroups } from '../utils/index'\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n} from './cmdk/index'\nimport { LucideIconDynamic } from './LucideIcon'\n\nconst MODAL_SLUG = 'command-menu'\n\ninterface CommandMenuContextType {\n closeMenu: () => void\n currentPage: CommandMenuPage\n groups: CommandMenuGroup[]\n isOpen: boolean\n items: CommandMenuItem[]\n openMenu: () => void\n setPage: (page: CommandMenuPage) => void\n toggleMenu: () => void\n}\n\nconst CommandMenuContext = createContext<CommandMenuContextType>({\n closeMenu: () => {},\n currentPage: 'main',\n groups: [],\n isOpen: false,\n items: [],\n openMenu: () => {},\n setPage: () => {},\n toggleMenu: () => {},\n})\n\nexport const useCommandMenu = () => {\n const context = useContext(CommandMenuContext)\n return context\n}\n\nconst ITEM_SELECTOR = `[cmdk-item=\"\"]`\n\nfunction getSelectedElement(containerRef: React.RefObject<HTMLElement | null>) {\n return containerRef.current?.querySelector(`${ITEM_SELECTOR}[aria-selected=\"true\"]`)\n}\n\nconst CommandMenuComponent: React.FC<{\n pluginConfig: PluginCommandMenuConfig\n}> = ({ pluginConfig }) => {\n const [search, setSearch] = useState('')\n const [submenuItems, setSubmenuItems] = useState<CommandMenuItem[]>([])\n const [isLoadingSubmenu, setIsLoadingSubmenu] = useState(false)\n const [isMac, setIsMac] = useState(false)\n\n const commandListRef = useRef<HTMLDivElement>(null)\n\n const { closeMenu, currentPage, groups, items, setPage } = useCommandMenu()\n const router = useRouter()\n const { t } = useTranslation<CustomTranslationsObject, CustomTranslationsKeys>()\n\n useEffect(() => {\n setIsMac(/Mac|iPhone|iPod|iPad/i.test(navigator.platform))\n }, [])\n\n const submenuEnabled = pluginConfig?.submenu?.enabled !== false\n const submenuShortcut = pluginConfig?.submenu?.shortcut || 'shift+enter'\n const blurBg = pluginConfig?.blurBg !== false\n\n const formatShortcutKey = (key: string): React.ReactNode => {\n // Handle compound shortcuts like \"Shift + Enter\"\n const parts = key.split('+').map((part) => part.trim())\n const elements = parts.map((part, index) => {\n const lowerPart = part.toLowerCase()\n let content: React.ReactNode\n\n if (lowerPart === 'ctrl' || lowerPart === 'cmd') {\n content = isMac ? <CommandIcon size={12} /> : 'Ctrl'\n } else if (lowerPart === 'meta') {\n content = isMac ? <CommandIcon size={12} /> : 'Ctrl'\n } else if (lowerPart === 'shift') {\n content = isMac ? <ArrowBigUp size={12} /> : 'Shift'\n } else if (lowerPart === 'alt') {\n content = isMac ? <Option size={12} /> : 'Alt'\n } else {\n content = part\n }\n\n return (\n <Fragment key={index}>\n {content}\n {!isMac && index < parts.length - 1 && ' + '}\n </Fragment>\n )\n })\n\n return <>{elements}</>\n }\n\n // Debounced search for submenu\n useEffect(() => {\n if (currentPage === 'main') {\n return\n }\n\n const fetchDocuments = async () => {\n if (currentPage.type !== 'collection-search') {\n return\n }\n\n setIsLoadingSubmenu(true)\n try {\n const searchParam = search\n ? `&where[${currentPage.useAsTitle}][like]=${encodeURIComponent(search)}`\n : ''\n const response = await fetch(\n `/api/${currentPage.slug}?limit=10${searchParam}&select[${currentPage.useAsTitle}]=true`,\n )\n const data = await response.json()\n\n if (data.docs && Array.isArray(data.docs)) {\n const docs: CommandMenuItem[] = data.docs.map((doc: GenericCollectionDocument) => ({\n slug: `${currentPage.slug}-${doc.id}`,\n type: 'custom' as const,\n action: {\n type: 'link',\n href: `/admin/collections/${currentPage.slug}/${doc.id}`,\n },\n icon: pluginConfig?.submenu?.icons?.[currentPage.slug] ?? undefined,\n label: doc[currentPage.useAsTitle] || doc.id,\n }))\n setSubmenuItems(docs)\n }\n } catch {\n setSubmenuItems([])\n } finally {\n setIsLoadingSubmenu(false)\n }\n }\n\n const timeoutId = setTimeout(fetchDocuments, 300)\n return () => clearTimeout(timeoutId)\n }, [search, currentPage, pluginConfig?.submenu?.icons])\n\n const handleBack = useCallback(() => {\n setPage('main')\n setSearch('')\n setSubmenuItems([])\n }, [setPage])\n\n const executeItemAction = useCallback(\n async (item: CommandMenuItem) => {\n // Execute the item's action\n switch (item.action.type) {\n case 'api':\n await fetch(item.action.href, {\n body: item.action.body ? JSON.stringify(item.action.body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n },\n method: item.action.method || 'GET',\n })\n break\n case 'link':\n router.push(item.action.href)\n break\n default:\n break\n }\n closeMenu()\n setSearch('')\n setPage('main')\n },\n [router, closeMenu, setPage],\n )\n\n const openSubmenu = useCallback(\n (item: CommandMenuItem) => {\n setPage({\n slug: item.slug,\n type: 'collection-search',\n label: item.label,\n useAsTitle: item.useAsTitle || 'id',\n useAsTitleLabel: item.useAsTitleLabel || item.useAsTitle || 'id',\n })\n setSearch('')\n //set isLoadingSubmenu to true to show loading state while fetching\n setIsLoadingSubmenu(true)\n setSubmenuItems([])\n },\n [setPage],\n )\n\n const handleSelect = useCallback(\n async (item: CommandMenuItem) => {\n await executeItemAction(item)\n },\n [executeItemAction],\n )\n\n // Handle keyboard events for navigation and back\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // ESC key for back navigation in submenu\n if (e.key === 'Escape' && currentPage !== 'main') {\n e.preventDefault()\n e.stopPropagation()\n handleBack()\n return\n }\n\n // Enter/Shift+Enter handling for collection submenu\n if (e.key === 'Enter' && currentPage === 'main') {\n const selectedElement = getSelectedElement(commandListRef)\n const itemType = selectedElement?.getAttribute('data-item-type')\n const itemSlug = selectedElement?.getAttribute('data-value')\n\n if (submenuEnabled && itemType === 'collection' && itemSlug) {\n const isShiftPressed = e.shiftKey\n const shouldOpenSubmenu =\n (submenuShortcut === 'shift+enter' && isShiftPressed) ||\n (submenuShortcut === 'enter' && !isShiftPressed)\n\n if (shouldOpenSubmenu) {\n e.preventDefault()\n e.stopPropagation()\n\n // Find the item in groups\n const item = groups.flatMap((g) => g.items).find((i) => i.slug === itemSlug)\n if (item) {\n openSubmenu(item)\n }\n return\n }\n }\n }\n }\n\n document.addEventListener('keydown', handleKeyDown, true)\n return () => document.removeEventListener('keydown', handleKeyDown, true)\n }, [currentPage, handleBack, submenuEnabled, submenuShortcut, openSubmenu, groups])\n\n const placeholder =\n currentPage === 'main'\n ? t('cmdkPlugin:search')\n : t('general:searchBy', {\n label: currentPage.useAsTitleLabel,\n })\n\n const shouldDisableFilter = currentPage !== 'main'\n\n // Static footer shortcuts based on current page\n const footerShortcuts =\n currentPage === 'main' && submenuEnabled && submenuShortcut === 'shift+enter'\n ? [\n { key: 'Enter', label: t('cmdkPlugin:navigate') },\n { key: 'Shift + Enter', label: t('cmdkPlugin:searchInCollection') },\n ]\n : currentPage === 'main' && submenuEnabled && submenuShortcut === 'enter'\n ? [\n { key: 'Enter', label: t('cmdkPlugin:searchInCollection') },\n { key: 'Shift + Enter', label: t('cmdkPlugin:navigate') },\n ]\n : currentPage === 'main'\n ? [{ key: 'Enter', label: t('cmdkPlugin:navigate') }]\n : [{ key: 'Enter', label: t('cmdkPlugin:open') }]\n\n const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Close modal only if clicking the backdrop (not the command itself)\n if (e.target === e.currentTarget) {\n closeMenu()\n }\n }\n\n return (\n <Modal slug={MODAL_SLUG}>\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}\n <div\n className={`command-modal ${blurBg ? 'command-modal--blur' : ''}`}\n onClick={handleBackdropClick}\n >\n <Command label=\"Command Menu\" shouldFilter={!shouldDisableFilter}>\n {/* Header for submenu navigation */}\n {currentPage !== 'main' && (\n <div className=\"command__header\">\n <button className=\"command__back-button\" onClick={handleBack} type=\"button\">\n <ChevronLeft size={16} />\n </button>\n <span className=\"command__header-label\">\n {t('cmdkPlugin:searchIn', { label: currentPage.label })}\n </span>\n </div>\n )}\n\n <CommandInput onValueChange={setSearch} placeholder={placeholder} value={search} />\n <CommandList ref={commandListRef}>\n <CommandEmpty>\n {isLoadingSubmenu ? t('cmdkPlugin:loading') : t('cmdkPlugin:noResults')}\n </CommandEmpty>\n\n {/* Main page view */}\n {currentPage === 'main' &&\n groups.map((group, index) => {\n if (group.items.length === 0) {\n return null\n }\n\n let titleName = group.title\n if (group.title === 'Collections') {\n titleName = t('general:collections')\n }\n if (group.title === 'Globals') {\n titleName = t('general:globals')\n }\n\n const isRenderSeparator = !(index === groups.length - 1 && items.length === 0)\n return (\n <Fragment key={group.title}>\n <CommandGroup heading={titleName}>\n {group.items.map((item) => {\n const isDynamicIcon = typeof item.icon === 'string'\n const IconComponent = isDynamicIcon ? null : (item.icon as LucideIcon)\n return (\n <CommandItem\n data-action-type={item.action.type}\n data-item-type={item.type}\n key={item.slug}\n keywords={[group.title]}\n onSelect={() => handleSelect(item)}\n value={item.slug}\n >\n {isDynamicIcon ? (\n <LucideIconDynamic\n className=\"command__item-icon\"\n name={item.icon as IconName}\n />\n ) : (\n IconComponent && <IconComponent className=\"command__item-icon\" />\n )}\n {item.label}\n {submenuEnabled && item.type === 'collection' && (\n <CommandShortcut>›</CommandShortcut>\n )}\n </CommandItem>\n )\n })}\n </CommandGroup>\n {isRenderSeparator && <CommandSeparator />}\n </Fragment>\n )\n })}\n\n {/* Stray items on main page */}\n {currentPage === 'main' &&\n items?.map((item) => (\n <CommandItem\n data-action-type={item.action.type}\n data-item-type={item.type}\n key={item.slug}\n onSelect={() => handleSelect(item)}\n value={item.slug}\n >\n {item.label}\n </CommandItem>\n ))}\n\n {/* Submenu page view */}\n {currentPage !== 'main' &&\n submenuItems.map((item) => {\n const isDynamicIcon = typeof item.icon === 'string'\n const IconComponent = isDynamicIcon ? null : (item.icon as LucideIcon)\n return (\n <CommandItem\n data-action-type={item.action.type}\n data-item-type={item.type}\n key={item.slug}\n onSelect={() => handleSelect(item)}\n value={item.slug}\n >\n {isDynamicIcon ? (\n <LucideIconDynamic\n className=\"command__item-icon\"\n name={item.icon as IconName}\n />\n ) : (\n IconComponent && <IconComponent className=\"command__item-icon\" />\n )}\n {item.label}\n </CommandItem>\n )\n })}\n </CommandList>\n\n {/* Footer with static shortcuts */}\n {footerShortcuts && footerShortcuts.length > 0 && (\n <div className=\"command__footer\">\n {footerShortcuts.map((shortcut, index) => (\n <span key={index}>\n <kbd>{formatShortcutKey(shortcut.key)}</kbd> {shortcut.label}\n </span>\n ))}\n </div>\n )}\n </Command>\n </div>\n </Modal>\n )\n}\n\nconst MemoizedCommandMenuComponent = memo(CommandMenuComponent)\n\nexport const CommandMenuProvider: React.FC<CommandMenuContextProps> = ({\n children,\n pluginConfig,\n}) => {\n const { closeModal, isModalOpen, openModal, toggleModal } = useModal()\n const [currentPage, setCurrentPage] = useState<CommandMenuPage>('main')\n\n useHotkeys(\n pluginConfig.shortcut || ['meta+k', 'ctrl+k'],\n (event) => {\n event.preventDefault()\n event.stopPropagation()\n toggleModal(MODAL_SLUG)\n },\n [toggleModal],\n )\n const { config } = useConfig()\n const { i18n } = useTranslation()\n const currentLang = i18n.language\n const { groups, items } = useMemo(() => {\n return createDefaultGroups(config, currentLang, pluginConfig)\n }, [config, currentLang, pluginConfig])\n\n return (\n <CommandMenuContext.Provider\n value={{\n closeMenu: () => closeModal(MODAL_SLUG),\n currentPage,\n groups,\n isOpen: isModalOpen(MODAL_SLUG),\n items,\n openMenu: () => openModal(MODAL_SLUG),\n setPage: setCurrentPage,\n toggleMenu: () => toggleModal(MODAL_SLUG),\n }}\n >\n {children}\n <MemoizedCommandMenuComponent pluginConfig={pluginConfig} />\n </CommandMenuContext.Provider>\n )\n}\n"],"names":["Modal","useConfig","useModal","useTranslation","ArrowBigUp","ChevronLeft","Command","CommandIcon","Option","useRouter","createContext","Fragment","memo","useCallback","useContext","useEffect","useMemo","useRef","useState","useHotkeys","createDefaultGroups","CommandEmpty","CommandGroup","CommandInput","CommandItem","CommandList","CommandSeparator","CommandShortcut","LucideIconDynamic","MODAL_SLUG","CommandMenuContext","closeMenu","currentPage","groups","isOpen","items","openMenu","setPage","toggleMenu","useCommandMenu","context","ITEM_SELECTOR","getSelectedElement","containerRef","current","querySelector","CommandMenuComponent","pluginConfig","search","setSearch","submenuItems","setSubmenuItems","isLoadingSubmenu","setIsLoadingSubmenu","isMac","setIsMac","commandListRef","router","t","test","navigator","platform","submenuEnabled","submenu","enabled","submenuShortcut","shortcut","blurBg","formatShortcutKey","key","parts","split","map","part","trim","elements","index","lowerPart","toLowerCase","content","size","length","fetchDocuments","type","searchParam","useAsTitle","encodeURIComponent","response","fetch","slug","data","json","docs","Array","isArray","doc","id","action","href","icon","icons","undefined","label","timeoutId","setTimeout","clearTimeout","handleBack","executeItemAction","item","body","JSON","stringify","headers","method","push","openSubmenu","useAsTitleLabel","handleSelect","handleKeyDown","e","preventDefault","stopPropagation","selectedElement","itemType","getAttribute","itemSlug","isShiftPressed","shiftKey","shouldOpenSubmenu","flatMap","g","find","i","document","addEventListener","removeEventListener","placeholder","shouldDisableFilter","footerShortcuts","handleBackdropClick","target","currentTarget","div","className","onClick","shouldFilter","button","span","onValueChange","value","ref","group","titleName","title","isRenderSeparator","heading","isDynamicIcon","IconComponent","data-action-type","data-item-type","keywords","onSelect","name","kbd","MemoizedCommandMenuComponent","CommandMenuProvider","children","closeModal","isModalOpen","openModal","toggleModal","setCurrentPage","event","config","i18n","currentLang","language","Provider"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { icons } from 'lucide-react';
2
+ export declare function LucideIconDynamic({ name, className, size, }: {
3
+ className?: string;
4
+ name: keyof typeof icons;
5
+ size?: number;
6
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { icons } from 'lucide-react';
3
+ export function LucideIconDynamic({ name, className, size }) {
4
+ const Icon = icons[name];
5
+ if (!Icon) {
6
+ return null;
7
+ }
8
+ return /*#__PURE__*/ _jsx(Icon, {
9
+ className: className,
10
+ size: size
11
+ });
12
+ }
13
+
14
+ //# sourceMappingURL=LucideIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/LucideIcon.tsx"],"sourcesContent":["import { icons } from 'lucide-react'\n\nexport function LucideIconDynamic({\n name,\n className,\n size,\n}: {\n className?: string\n name: keyof typeof icons\n size?: number\n}) {\n const Icon = icons[name]\n if (!Icon) {\n return null\n }\n\n return <Icon className={className} size={size}></Icon>\n}\n"],"names":["icons","LucideIconDynamic","name","className","size","Icon"],"mappings":";AAAA,SAASA,KAAK,QAAQ,eAAc;AAEpC,OAAO,SAASC,kBAAkB,EAChCC,IAAI,EACJC,SAAS,EACTC,IAAI,EAKL;IACC,MAAMC,OAAOL,KAAK,CAACE,KAAK;IACxB,IAAI,CAACG,MAAM;QACT,OAAO;IACT;IAEA,qBAAO,KAACA;QAAKF,WAAWA;QAAWC,MAAMA;;AAC3C"}
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { LucideIcon } from 'lucide-react';
2
- import type { IconName } from 'lucide-react/dynamic';
1
+ import type { icons, LucideIcon } from 'lucide-react';
3
2
  import type { CollectionSlug, GlobalSlug } from 'payload';
3
+ export type IconName = keyof typeof icons;
4
4
  export type LocalizedString = {
5
5
  [locale: string]: string;
6
6
  } | string;
@@ -56,16 +56,12 @@ export type PluginCommandMenuConfig = {
56
56
  * Custom icons for collections.
57
57
  * @default <Files/>
58
58
  */
59
- collections?: {
60
- [key: CollectionSlug]: IconName;
61
- };
59
+ collections?: Partial<Record<CollectionSlug, IconName>>;
62
60
  /**
63
61
  * Custom icons for globals.
64
62
  * @default <Globe/>
65
63
  */
66
- globals?: {
67
- [key: GlobalSlug]: IconName;
68
- };
64
+ globals?: Partial<Record<GlobalSlug, IconName>>;
69
65
  };
70
66
  /**
71
67
  * Configuration for the search button in the admin navigation.
@@ -122,9 +118,7 @@ export type PluginCommandMenuConfig = {
122
118
  *
123
119
  * @default null
124
120
  */
125
- icons?: {
126
- [key: CollectionSlug]: IconName;
127
- };
121
+ icons?: Partial<Record<CollectionSlug, IconName>>;
128
122
  /**
129
123
  * Keyboard shortcut to open collection submenu.
130
124
  * - 'shift+enter': Shift+Enter opens submenu, Enter navigates to collection list
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { LucideIcon } from 'lucide-react'\nimport type { IconName } from 'lucide-react/dynamic'\nimport type { CollectionSlug, GlobalSlug } from 'payload'\n\nexport type LocalizedString = { [locale: string]: string } | string\n\nexport type InternalIcon = IconName | LucideIcon\n\n/**\n * Custom menu item, for configuration.\n * Will be mapped to CommandMenuItem internally.\n */\nexport type CustomMenuItem = {\n action: CommandMenuAction\n icon?: IconName\n label: LocalizedString\n slug: string\n type: 'item'\n}\n\n/**\n * Custom menu group, for configuration.\n * Will be mapped to CommandMenuGroup internally.\n *\n * Groups will be merged if they have the same title.\n */\nexport type CustomMenuGroup = {\n items: CustomMenuItem[]\n title: LocalizedString\n type: 'group'\n}\n/**\n * Full serializable config for the plugin.\n */\nexport type PluginCommandMenuConfig = {\n /**\n * Enable backdrop blur effect\n * @default true\n */\n blurBg?: boolean\n /**\n * Custom items or groups to add to the command menu.\n */\n customItems?: (CustomMenuGroup | CustomMenuItem)[]\n /**\n * Disable the plugin functionality\n * @default false\n */\n disabled?: boolean\n /**\n * Custom icons for collections and globals.\n * Key is the collection slug, value is the icon name from lucide-react.\n * Collections default icon - Files,\n * Globals default icon - Globe.\n */\n icons?: {\n /**\n * Custom icons for collections.\n * @default <Files/>\n */\n collections?: {\n [key: CollectionSlug]: IconName\n }\n /**\n * Custom icons for globals.\n * @default <Globe/>\n */\n globals?: {\n [key: GlobalSlug]: IconName\n }\n }\n /**\n * Configuration for the search button in the admin navigation.\n * Set to false to disable the search button.\n * @default { position: 'actions' }\n */\n searchButton?:\n | {\n /**\n * Position of the search button in the admin navigation.\n * @default 'actions'\n */\n position?: 'actions' | 'nav'\n }\n | false\n /**\n * Keyboard shortcut to open the command menu.\n * Can be a single shortcut string or an array of shortcuts for cross-platform support.\n * @default ['meta+k', 'ctrl+k']\n * @example 'mod+k' or ['meta+k', 'ctrl+k']\n *\n * More details here - https://react-hotkeys-hook.vercel.app/docs/intro\n */\n shortcut?: string | string[]\n /**\n * Specify which collections slugs remove from the command menu.\n * @default ['payload-migrations','payload-preferences','payload-locked-documents']\n *\n * You can also provide an object with `ignoreList` and `replaceDefaults` properties.\n * `replaceDefaults` allows you to completely replace the default slugs to ignore instead of appending to them.\n */\n slugsToIgnore?:\n | {\n /**\n * List of collection/global slugs to ignore in the command menu.\n */\n ignoreList: CollectionSlug[]\n /**\n * Whether to replace the default slugs to ignore instead of appending to them.\n */\n replaceDefaults?: boolean\n }\n | CollectionSlug[]\n /**\n * Configure submenu behavior for collections.\n * When enabled, users can search within a collection's documents.\n * @default { enabled: true, shortcut: 'shift+enter' }\n */\n submenu?: {\n /**\n * Enable or disable submenu functionality.\n * @default true\n */\n enabled?: boolean\n /**\n * Custom icons for collection submenus.\n * Key is the collection slug, value is the icon name from lucide-react.\n *\n * @default null\n */\n icons?: {\n [key: CollectionSlug]: IconName\n }\n /**\n * Keyboard shortcut to open collection submenu.\n * - 'shift+enter': Shift+Enter opens submenu, Enter navigates to collection list\n * - 'enter': Enter opens submenu, Shift+Enter navigates to collection list\n * @default 'shift+enter'\n */\n shortcut?: 'enter' | 'shift+enter'\n }\n}\n\nexport interface CommandMenuContextProps {\n children: React.ReactNode\n pluginConfig: PluginCommandMenuConfig\n}\n\nexport interface CommandMenuActionLink {\n href: string\n type: 'link'\n}\n\nexport interface CommandMenuActionAPICall {\n body?: {\n [key: string]: unknown\n }\n href: string\n /**\n * HTTP method to use for the API call.\n * @default 'GET'\n */\n method?: 'DELETE' | 'GET' | 'POST' | 'PUT'\n type: 'api'\n}\n\nexport type CommandMenuAction = CommandMenuActionAPICall | CommandMenuActionLink\n\nexport interface CommandMenuItem {\n /**\n * Action to perform when the command menu item is selected.\n */\n action: CommandMenuAction\n icon?: InternalIcon\n label: string\n slug: string\n /**\n * Type of the command menu item. Used for grouping and icons.\n * @default 'custom'\n */\n type: 'collection' | 'custom' | 'global'\n\n /**\n * Field name used as title for collection documents.\n * Only applicable for collection type items.\n * Defaults to 'id' if not specified.\n */\n useAsTitle?: string\n /**\n * Label for the field used as title for collection documents.\n * Only applicable for collection type items.\n *\n * Used in submenu search placeholder.\n */\n useAsTitleLabel?: string\n}\n\nexport interface CommandMenuGroup {\n items: CommandMenuItem[]\n title: string\n}\n\n/**\n * Page state for command menu navigation.\n * - 'main': Default view showing all collections/globals/custom items\n * - CollectionSearchPage: Submenu view for searching within a specific collection\n */\nexport type CommandMenuPage =\n | 'main'\n | {\n /**\n * Collection label for display\n */\n label: string\n /**\n * Collection slug\n */\n slug: string\n /**\n * Page type identifier\n */\n type: 'collection-search'\n /**\n * Field name to use as document title\n */\n useAsTitle: string\n /**\n * Label for the field used as title\n */\n useAsTitleLabel: string\n }\n\n/**\n * Generic document type for collections, with dynamic keys.\n * We assume values are either string or number for simplicity, useAsTitle is making sure of that.\n */\nexport type GenericCollectionDocument = {\n [key: string]: number | string\n id: string\n}\n"],"names":[],"mappings":"AAwOA;;;CAGC,GACD,WAGC"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { icons, LucideIcon } from 'lucide-react'\nimport type { CollectionSlug, GlobalSlug } from 'payload'\n\nexport type IconName = keyof typeof icons\n\nexport type LocalizedString = { [locale: string]: string } | string\n\nexport type InternalIcon = IconName | LucideIcon\n\n/**\n * Custom menu item, for configuration.\n * Will be mapped to CommandMenuItem internally.\n */\nexport type CustomMenuItem = {\n action: CommandMenuAction\n icon?: IconName\n label: LocalizedString\n slug: string\n type: 'item'\n}\n\n/**\n * Custom menu group, for configuration.\n * Will be mapped to CommandMenuGroup internally.\n *\n * Groups will be merged if they have the same title.\n */\nexport type CustomMenuGroup = {\n items: CustomMenuItem[]\n title: LocalizedString\n type: 'group'\n}\n/**\n * Full serializable config for the plugin.\n */\nexport type PluginCommandMenuConfig = {\n /**\n * Enable backdrop blur effect\n * @default true\n */\n blurBg?: boolean\n /**\n * Custom items or groups to add to the command menu.\n */\n customItems?: (CustomMenuGroup | CustomMenuItem)[]\n /**\n * Disable the plugin functionality\n * @default false\n */\n disabled?: boolean\n /**\n * Custom icons for collections and globals.\n * Key is the collection slug, value is the icon name from lucide-react.\n * Collections default icon - Files,\n * Globals default icon - Globe.\n */\n icons?: {\n /**\n * Custom icons for collections.\n * @default <Files/>\n */\n collections?: Partial<Record<CollectionSlug, IconName>>\n /**\n * Custom icons for globals.\n * @default <Globe/>\n */\n globals?: Partial<Record<GlobalSlug, IconName>>\n }\n /**\n * Configuration for the search button in the admin navigation.\n * Set to false to disable the search button.\n * @default { position: 'actions' }\n */\n searchButton?:\n | {\n /**\n * Position of the search button in the admin navigation.\n * @default 'actions'\n */\n position?: 'actions' | 'nav'\n }\n | false\n /**\n * Keyboard shortcut to open the command menu.\n * Can be a single shortcut string or an array of shortcuts for cross-platform support.\n * @default ['meta+k', 'ctrl+k']\n * @example 'mod+k' or ['meta+k', 'ctrl+k']\n *\n * More details here - https://react-hotkeys-hook.vercel.app/docs/intro\n */\n shortcut?: string | string[]\n /**\n * Specify which collections slugs remove from the command menu.\n * @default ['payload-migrations','payload-preferences','payload-locked-documents']\n *\n * You can also provide an object with `ignoreList` and `replaceDefaults` properties.\n * `replaceDefaults` allows you to completely replace the default slugs to ignore instead of appending to them.\n */\n slugsToIgnore?:\n | {\n /**\n * List of collection/global slugs to ignore in the command menu.\n */\n ignoreList: CollectionSlug[]\n /**\n * Whether to replace the default slugs to ignore instead of appending to them.\n */\n replaceDefaults?: boolean\n }\n | CollectionSlug[]\n /**\n * Configure submenu behavior for collections.\n * When enabled, users can search within a collection's documents.\n * @default { enabled: true, shortcut: 'shift+enter' }\n */\n submenu?: {\n /**\n * Enable or disable submenu functionality.\n * @default true\n */\n enabled?: boolean\n /**\n * Custom icons for collection submenus.\n * Key is the collection slug, value is the icon name from lucide-react.\n *\n * @default null\n */\n icons?: Partial<Record<CollectionSlug, IconName>>\n /**\n * Keyboard shortcut to open collection submenu.\n * - 'shift+enter': Shift+Enter opens submenu, Enter navigates to collection list\n * - 'enter': Enter opens submenu, Shift+Enter navigates to collection list\n * @default 'shift+enter'\n */\n shortcut?: 'enter' | 'shift+enter'\n }\n}\n\nexport interface CommandMenuContextProps {\n children: React.ReactNode\n pluginConfig: PluginCommandMenuConfig\n}\n\nexport interface CommandMenuActionLink {\n href: string\n type: 'link'\n}\n\nexport interface CommandMenuActionAPICall {\n body?: {\n [key: string]: unknown\n }\n href: string\n /**\n * HTTP method to use for the API call.\n * @default 'GET'\n */\n method?: 'DELETE' | 'GET' | 'POST' | 'PUT'\n type: 'api'\n}\n\nexport type CommandMenuAction = CommandMenuActionAPICall | CommandMenuActionLink\n\nexport interface CommandMenuItem {\n /**\n * Action to perform when the command menu item is selected.\n */\n action: CommandMenuAction\n icon?: InternalIcon\n label: string\n slug: string\n /**\n * Type of the command menu item. Used for grouping and icons.\n * @default 'custom'\n */\n type: 'collection' | 'custom' | 'global'\n\n /**\n * Field name used as title for collection documents.\n * Only applicable for collection type items.\n * Defaults to 'id' if not specified.\n */\n useAsTitle?: string\n /**\n * Label for the field used as title for collection documents.\n * Only applicable for collection type items.\n *\n * Used in submenu search placeholder.\n */\n useAsTitleLabel?: string\n}\n\nexport interface CommandMenuGroup {\n items: CommandMenuItem[]\n title: string\n}\n\n/**\n * Page state for command menu navigation.\n * - 'main': Default view showing all collections/globals/custom items\n * - CollectionSearchPage: Submenu view for searching within a specific collection\n */\nexport type CommandMenuPage =\n | 'main'\n | {\n /**\n * Collection label for display\n */\n label: string\n /**\n * Collection slug\n */\n slug: string\n /**\n * Page type identifier\n */\n type: 'collection-search'\n /**\n * Field name to use as document title\n */\n useAsTitle: string\n /**\n * Label for the field used as title\n */\n useAsTitleLabel: string\n }\n\n/**\n * Generic document type for collections, with dynamic keys.\n * We assume values are either string or number for simplicity, useAsTitle is making sure of that.\n */\nexport type GenericCollectionDocument = {\n [key: string]: number | string\n id: string\n}\n"],"names":[],"mappings":"AAmOA;;;CAGC,GACD,WAGC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veiag/payload-cmdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A command menu plugin for Payload CMS to enhance navigation and accessibility within the admin panel.",
5
5
  "author": "VeiaG",
6
6
  "license": "MIT",