@parallelworks/ui 0.36.0 → 0.37.0

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.
Files changed (79) hide show
  1. package/README.md +16 -0
  2. package/dist/ai/agent/permissions.d.ts +2 -2
  3. package/dist/ai/agent/permissions.js +3 -1
  4. package/dist/ai/components/agent/PermissionPicker.js +1 -0
  5. package/dist/ai/strings.d.ts +2 -0
  6. package/dist/ai/strings.js +2 -0
  7. package/dist/components/Dropdown.d.ts +2 -0
  8. package/dist/components/Dropdown.js +7 -2
  9. package/dist/components/Input.d.ts +11 -6
  10. package/dist/components/Input.js +93 -74
  11. package/dist/components/Provider.d.ts +31 -0
  12. package/dist/components/Provider.js +50 -2
  13. package/dist/editing.d.ts +404 -0
  14. package/dist/editor/EditorField.js +1 -1
  15. package/dist/editor/Monaco.d.ts +15 -1
  16. package/dist/editor/Monaco.js +117 -13
  17. package/dist/editor/editorModel.d.ts +5 -0
  18. package/dist/editor/editorModel.js +23 -0
  19. package/dist/editor/index.d.ts +4 -0
  20. package/dist/editor/index.js +5 -1
  21. package/dist/editor/lintContext.d.ts +21 -0
  22. package/dist/editor/lintContext.js +136 -0
  23. package/dist/editor/lintOwner.d.ts +2 -0
  24. package/dist/editor/lintOwner.js +5 -0
  25. package/dist/editor/nestedText.d.ts +13 -0
  26. package/dist/editor/nestedText.js +15 -0
  27. package/dist/editor/reveal.d.ts +4 -0
  28. package/dist/editor/reveal.js +15 -0
  29. package/dist/editor/settingsYaml.d.ts +12 -0
  30. package/dist/editor/settingsYaml.js +41 -0
  31. package/dist/form/Fields/DropdownField.js +1 -1
  32. package/dist/form/Fields/DurationField.js +1 -1
  33. package/dist/form/Form.js +1 -1
  34. package/dist/form/fieldRegistry.js +1 -1
  35. package/dist/form/index.js +5 -5
  36. package/dist/graph/InputDialog.d.ts +80 -0
  37. package/dist/graph/InputDialog.js +596 -0
  38. package/dist/graph/ProblemsButton.d.ts +9 -0
  39. package/dist/graph/ProblemsButton.js +61 -0
  40. package/dist/graph/ShortcutsButton.d.ts +15 -0
  41. package/dist/graph/SuggestionInput.d.ts +18 -0
  42. package/dist/graph/ToolbarPopover.d.ts +8 -0
  43. package/dist/graph/ToolbarPopover.js +71 -0
  44. package/dist/graph/editorApi.d.ts +51 -0
  45. package/dist/graph/editorChrome.d.ts +27 -0
  46. package/dist/graph/editorFields.d.ts +180 -0
  47. package/dist/graph/editorPrimitives.d.ts +60 -0
  48. package/dist/graph/editorPrimitives.js +59 -0
  49. package/dist/graph/editorStrings.d.ts +695 -0
  50. package/dist/graph/editorStrings.js +699 -0
  51. package/dist/graph/expressionRefs.d.ts +12 -0
  52. package/dist/graph/fieldProblems.d.ts +32 -0
  53. package/dist/graph/index.d.ts +6 -0
  54. package/dist/graph/index.js +5 -1
  55. package/dist/graph/inputLayout.d.ts +25 -0
  56. package/dist/graph/inputRefs.d.ts +103 -0
  57. package/dist/graph/records.d.ts +3 -0
  58. package/dist/graph/records.js +7 -0
  59. package/dist/graph/refusalText.d.ts +6 -0
  60. package/dist/graph/settingsViews.d.ts +26 -0
  61. package/dist/graph/usesInputs.d.ts +17 -0
  62. package/dist/graph/usesInputs.js +40 -0
  63. package/dist/icons/bi/BiRedo.js +16 -0
  64. package/dist/icons/bi/BiUndo.js +16 -0
  65. package/dist/icons/lu/LuBraces.js +27 -0
  66. package/dist/icons/lu/LuCode.js +27 -0
  67. package/dist/icons/lu/LuKeyboard.js +71 -0
  68. package/dist/icons/lu/LuNetwork.js +63 -0
  69. package/dist/icons/lu/LuTextCursorInput.js +45 -0
  70. package/dist/icons.d.ts +2 -2
  71. package/dist/icons.js +8 -1
  72. package/dist/index.d.ts +2 -1
  73. package/dist/index.js +2 -2
  74. package/dist/list/ActionToolbar.d.ts +2 -0
  75. package/dist/list/ActionToolbar.js +18 -5
  76. package/dist/list/RowContextMenu.d.ts +10 -1
  77. package/dist/list/RowContextMenu.js +185 -30
  78. package/dist/styles.css +1 -1
  79. package/package.json +1 -1
package/dist/icons.js CHANGED
@@ -6,9 +6,11 @@ import { BiError } from "./icons/bi/BiError.js";
6
6
  import { BiExpandVertical } from "./icons/bi/BiExpandVertical.js";
7
7
  import { BiPause } from "./icons/bi/BiPause.js";
8
8
  import { BiPlay } from "./icons/bi/BiPlay.js";
9
+ import { BiRedo } from "./icons/bi/BiRedo.js";
9
10
  import { BiSolidCheckShield } from "./icons/bi/BiSolidCheckShield.js";
10
11
  import { BiSolidTrashAlt } from "./icons/bi/BiSolidTrashAlt.js";
11
12
  import { BiStop } from "./icons/bi/BiStop.js";
13
+ import { BiUndo } from "./icons/bi/BiUndo.js";
12
14
  import { BsArrowsCollapse } from "./icons/bs/BsArrowsCollapse.js";
13
15
  import { BsBank2 } from "./icons/bs/BsBank2.js";
14
16
  import { BsBriefcase } from "./icons/bs/BsBriefcase.js";
@@ -192,25 +194,30 @@ import { IoSettingsOutline } from "./icons/io5/IoSettingsOutline.js";
192
194
  import { IoWarningOutline } from "./icons/io5/IoWarningOutline.js";
193
195
  import { LuArrowRight } from "./icons/lu/LuArrowRight.js";
194
196
  import { LuBadgeCheck } from "./icons/lu/LuBadgeCheck.js";
197
+ import { LuBraces } from "./icons/lu/LuBraces.js";
195
198
  import { LuBrainCircuit } from "./icons/lu/LuBrainCircuit.js";
196
199
  import { LuCalendar } from "./icons/lu/LuCalendar.js";
197
200
  import { LuCheck } from "./icons/lu/LuCheck.js";
198
201
  import { LuChevronLeft } from "./icons/lu/LuChevronLeft.js";
199
202
  import { LuChevronRight } from "./icons/lu/LuChevronRight.js";
203
+ import { LuCode } from "./icons/lu/LuCode.js";
200
204
  import { LuExternalLink } from "./icons/lu/LuExternalLink.js";
201
205
  import { LuEye } from "./icons/lu/LuEye.js";
202
206
  import { LuEyeOff } from "./icons/lu/LuEyeOff.js";
203
207
  import { LuFolderTree } from "./icons/lu/LuFolderTree.js";
204
208
  import { LuIdCard } from "./icons/lu/LuIdCard.js";
209
+ import { LuKeyboard } from "./icons/lu/LuKeyboard.js";
205
210
  import { LuLogs } from "./icons/lu/LuLogs.js";
206
211
  import { LuMail } from "./icons/lu/LuMail.js";
207
212
  import { LuMegaphone } from "./icons/lu/LuMegaphone.js";
208
213
  import { LuMoon } from "./icons/lu/LuMoon.js";
214
+ import { LuNetwork } from "./icons/lu/LuNetwork.js";
209
215
  import { LuPartyPopper } from "./icons/lu/LuPartyPopper.js";
210
216
  import { LuSettings2 } from "./icons/lu/LuSettings2.js";
211
217
  import { LuSheet } from "./icons/lu/LuSheet.js";
212
218
  import { LuShield } from "./icons/lu/LuShield.js";
213
219
  import { LuSun } from "./icons/lu/LuSun.js";
220
+ import { LuTextCursorInput } from "./icons/lu/LuTextCursorInput.js";
214
221
  import { LuX } from "./icons/lu/LuX.js";
215
222
  import { LuZoomIn } from "./icons/lu/LuZoomIn.js";
216
223
  import { LuZoomOut } from "./icons/lu/LuZoomOut.js";
@@ -254,4 +261,4 @@ import { VscPass } from "./icons/vsc/VscPass.js";
254
261
  import { VscSplitHorizontal } from "./icons/vsc/VscSplitHorizontal.js";
255
262
  import { VscTerminalPowershell } from "./icons/vsc/VscTerminalPowershell.js";
256
263
  import { ErrorCheckmark, LoaderIcon, SuccessCheckmark } from "./components/StatusIcons.js";
257
- export { TbApi as APIIcon, FaUsers as AccessIcon, FaPlus as AddIcon, BsPersonPlus as AddUserIcon, FiAlertCircle as AlertCircleIcon, TbAlertTriangleFilled as AlertFillIcon, TbAlertTriangle as AlertIcon, FaAmazon as AmazonIcon, FaAngleDown as AngleDownIcon, FaAngleLeft as AngleLeftIcon, FaAngleRight as AngleRightIcon, FaAngleUp as AngleUpIcon, SiAnthropic as AnthropicIcon, FaApple as AppleIcon, HiOutlineArchive as ArchiveIcon, FaArrowDown as ArrowDownIcon, FaArrowLeft as ArrowLeftIcon, FaArrowRight as ArrowRightIcon, LuArrowRight as ArrowRightStrokeIcon, FaArrowUp as ArrowUpIcon, FaPaperclip as AttachmentIcon, BsBriefcase as BriefcaseIcon, BsBucket as BucketIcon, IoMdBuild as BuildWorkflowIcon, LuCalendar as CalendarIcon, BsCalendarX as CalendarOffIcon, TiCancel as CancelIcon, FaCaretDown as CaretDownIcon, LuPartyPopper as CelebrateIcon, FaCentos as CentOSIcon, FaChartLine as ChartIcon, BsZoomIn as ChartZoomIcon, FaComments as ChatIcon, FaCheck as CheckIcon, VscPass as CheckMarkIcon, LuCheck as CheckStrokeIcon, BsChevronDoubleDown as ChevronDoubleDownIcon, BsChevronDoubleUp as ChevronDoubleUpIcon, FaChevronDown as ChevronDownIcon, FiChevronDown as ChevronDownStrokeIcon, LuChevronLeft as ChevronLeftIcon, LuChevronRight as ChevronRightIcon, FaChevronUp as ChevronUpIcon, FaChrome as ChromeIcon, MdClear as ClearIcon, BsClipboardCheck as ClipboardCheckIcon, HiOutlineClipboardCopy as ClipboardIcon, FiClock as ClockIcon, IoMdClose as CloseIcon, FaCloud as CloudIcon, IoCloudUploadOutline as CloudUploadIcon, GrServerCluster as ClusterIcon, FaCog as CogIcon, BsArrowsCollapse as CollapseIcon, BsLayoutThreeColumns as ColumnsIcon, BsChatLeft as CommentIcon, GoGitCommit as CommitIcon, GrCloudComputer as ComputeIcon, PiPlugsConnectedFill as ConnectIcon, FiCopy as CopyIcon, FaDollarSign as CostDashboardIcon, FaWandMagicSparkles as CustomizeIcon, FaDebian as DebianIcon, MdOutlineMoneyOff as DisableCostIcon, TbUserOff as DisableUserIcon, FiHardDrive as DiskIcon, LuSettings2 as DisplayIcon, FaDocker as DockerIcon, IoDocumentTextOutline as DocumentIcon, FiDownload as DownloadFileIcon, FaCloudDownloadAlt as DownloadIcon, MdDragHandle as DragHandleIcon, HiDuplicate as DuplicateIcon, FaEdge as EdgeIcon, FaEdit as EditIcon, VscLayoutSidebarLeft as EditorIcon, BsMortarboard as EducationIcon, MdOutlineAttachMoney as EnableCostIcon, TbUser as EnableUserIcon, TbWorldShare as EndpointIcon, ErrorCheckmark, BiError as ErrorIcon, LuLogs as EventsIcon, FaRunning as ExecuteWorkflow, FaExpand as ExpandIcon, BiExpandVertical as ExpandVerticalIcon, LuExternalLink as ExternalLink, LuEye as EyeIcon, LuEyeOff as EyeOffIcon, HiMiniXCircle as FailIcon, IoHeart as FavoriteIcon, IoHeartOutline as FavoriteOutlineIcon, FaStar as FeaturedIcon, FiFile as FileIcon, FaFile as FileSolidIcon, FiFileText as FileTextIcon, BsFiles as FilesIcon, IoFileTrayFullOutline as FilesystemIcon, FaFilterCircleXmark as FilterClearIcon, FaFilter as FilterIcon, FaFirefoxBrowser as FirefoxIcon, FaFlask as FlaskIcon, FaRegFolder as FolderIcon, FaRegFolderOpen as FolderOpenIcon, FaFolder as FolderSolidIcon, LuFolderTree as FolderTreeIcon, GoSkip as ForbiddenIcon, GoRepoForked as ForkIcon, HiCog as GearIcon, FaCogs as GearsIcon, FaGithub as GitHubIcon, FaGitlab as GitLabIcon, FaGlobe as GlobeIcon, BsBank2 as GovernmentIcon, BsGrid as GridIcon, FiActivity as HealthMonitoringIcon, SiHelm as HelmIcon, FaEye as HiddenFalseIcon, FaEyeSlash as HiddenTrueIcon, FiRotateCcw as HistoryIcon, HiOutlineHome as HomeIcon, LuIdCard as IdCardIcon, FaRegFileImage as ImageIcon, FaImage as ImageSolidIcon, GiSpy as ImpersonateIcon, GrInbox as InboxIcon, IoInformationCircleOutline as InfoCircleIcon, FaInfoCircle as InfoIcon, BsLayers as InfrastructureLayersIcon, MdInstallDesktop as InstallIcon, FaLocationDot as IpAddressIcon, GoIssueOpened as IssueIcon, VscJson as JsonIcon, FaKey as KeyIcon, SiKubernetes as KubernetesIcon, PiRectangleDashed as KubernetesNamespaceIcon, HiMiniLanguage as LanguageIcon, FaBalanceScale as LegalIcon, LuBadgeCheck as LicenseIcon, FaLink as LinkIcon, FaLinkedin as LinkedInIcon, FaLinux as LinuxIcon, BsListUl as ListViewIcon, LoaderIcon, FaLock as LockIcon, MdSmartphone as MFA, LuMail as MailIcon, BsGeoAlt as MapPinIcon, FaGlobeAmericas as MarketplaceIcon, LuMegaphone as MegaphoneIcon, BsThreeDotsVertical as MenuIcon, VscChromeMinimize as MinimizeIcon, BsDash as MinusIcon, LuBrainCircuit as MlIcon, BsCurrencyDollar as MoneyIcon, GrTasks as MonitorIcon, LuMoon as MoonIcon, BsThreeDots as MoreIcon, BsMusicNoteBeamed as MusicIcon, BiBellOff as MuteIcon, TbEdit as NewChatIcon, FaUpRightFromSquare as NewWindowIcon, FaRegCircle as NotRunningIcon, IoIosNotifications as NotificationFillIcon, FaInbox as NotificationInboxIcon, FaOpenid as OIDCIcon, BsOpenai as OpenAIIcon, PiArrowBendUpRightBold as OpenInNewGraphIcon, FaOpera as OperaIcon, BiBuildings as OrganizationIcon, FaRocket as PartnerIcon, FaKey as PasswordIcon, BiPause as PauseIcon, FaRegFilePdf as PdfIcon, FaFilePdf as PdfSolidIcon, BsTelephone as PhoneIcon, FaChartPie as PieChartIcon, BsStarFill as PinFilledIcon, BsStar as PinIcon, GoPlus as PlusOutlineIcon, FaPowerOff as PowerIcon, VscTerminalPowershell as PowershellIcon, FaPrint as PrintIcon, FaGlobeAmericas as PublishIcon, GoGitPullRequest as PullRequestIcon, FaQrcode as QRCodeIcon, MdPieChart as QuotaIcon, FaRedhat as RedHatIcon, FaArrowsRotate as RefreshArrowsIcon, MdRefresh as RefreshIcon, MdReplay as ReplayIcon, FaLayerGroup as ResourceGroupIcon, FaUndoAlt as RetryIcon, FaRobot as RobotIcon, AiOutlineRollback as RollbackIcon, VscTerminalPowershell as RunWorkflowIcon, ImSpinner5 as RunningIcon, FaSafari as SafariIcon, FaSave as SaveIcon, FaList as SchedulerIcon, FaSearch as SearchIcon, BsSearch as SearchOutlineIcon, BsSend as SendIcon, HiServer as ServerIcon, IoSettingsOutline as SettingsIcon, PiShareBold as ShareIcon, FaUsers as SharingIcon, FaShieldAlt as ShieldAltIcon, BiSolidCheckShield as ShieldIcon, BsShieldSlash as ShieldOffIcon, LuShield as ShieldOutlineIcon, FaCompress as ShrinkIcon, TbLayoutSidebarRightCollapse as SidebarCloseIcon, TbLayoutSidebar as SidebarIcon, TbLayoutSidebarLeftCollapse as SidebarOpenIcon, GoSignOut as SignOutIcon, HiMiniMinusCircle as SkipIcon, FaSlack as SlackIcon, FaDesktop as SnapshotIcon, TiArrowSortedDown as SortDownIcon, TiArrowUnsorted as SortUnsortedIcon, TiArrowSortedUp as SortUpIcon, HiSparkles as SparklesIcon, VscSplitHorizontal as SplitIcon, LuSheet as SpreadsheetIcon, BiPlay as StartIcon, BsStopCircle as StopCircleIcon, BiStop as StopIcon, FaStop as StopSolidIcon, GrStorage as StorageIcon, TbWorldWww as SubdomainIcon, SuccessCheckmark, HiMiniCheckCircle as SuccessIcon, LuSun as SunIcon, FaSuse as SuseIcon, BsTag as TagIcon, FaTerminal as TerminalIcon, TbBrain as ThinkingIcon, FaTimes as TimesIcon, HiQuestionMarkCircle as TooltipIcon, BiSolidTrashAlt as TrashIcon, TbBuildingTunnel as TunnelIcon, FaUbuntu as UbuntuIcon, IoHeartDislike as UnfavoriteIcon, FaUnlink as UnlinkIcon, BiBell as UnmuteIcon, FiUpload as UploadIcon, FaQuestionCircle as UserGuideIcon, FaUser as UserIcon, BsTerminalFill as UserWorkspaceFillIcon, BsTerminal as UserWorkspaceIcon, FaUsers as UsersIcon, GoVideo as VideoIcon, IoWarningOutline as WarningIcon, FaExclamationTriangle as WarningTriangleIcon, FaWindows as WindowsIcon, FiX as XIcon, LuX as XStrokeIcon, FaXTwitter as XTwitterIcon, FiZap as ZapIcon, BsFileEarmarkZip as ZipIcon, LuZoomIn as ZoomInIcon, LuZoomOut as ZoomOutIcon };
264
+ export { TbApi as APIIcon, FaUsers as AccessIcon, FaPlus as AddIcon, BsPersonPlus as AddUserIcon, FiAlertCircle as AlertCircleIcon, TbAlertTriangleFilled as AlertFillIcon, TbAlertTriangle as AlertIcon, FaAmazon as AmazonIcon, FaAngleDown as AngleDownIcon, FaAngleLeft as AngleLeftIcon, FaAngleRight as AngleRightIcon, FaAngleUp as AngleUpIcon, SiAnthropic as AnthropicIcon, FaApple as AppleIcon, HiOutlineArchive as ArchiveIcon, FaArrowDown as ArrowDownIcon, FaArrowLeft as ArrowLeftIcon, FaArrowRight as ArrowRightIcon, LuArrowRight as ArrowRightStrokeIcon, FaArrowUp as ArrowUpIcon, FaPaperclip as AttachmentIcon, BsBriefcase as BriefcaseIcon, BsBucket as BucketIcon, IoMdBuild as BuildWorkflowIcon, LuCalendar as CalendarIcon, BsCalendarX as CalendarOffIcon, TiCancel as CancelIcon, FaCaretDown as CaretDownIcon, LuPartyPopper as CelebrateIcon, FaCentos as CentOSIcon, FaChartLine as ChartIcon, BsZoomIn as ChartZoomIcon, FaComments as ChatIcon, FaCheck as CheckIcon, VscPass as CheckMarkIcon, LuCheck as CheckStrokeIcon, BsChevronDoubleDown as ChevronDoubleDownIcon, BsChevronDoubleUp as ChevronDoubleUpIcon, FaChevronDown as ChevronDownIcon, FiChevronDown as ChevronDownStrokeIcon, LuChevronLeft as ChevronLeftIcon, LuChevronRight as ChevronRightIcon, FaChevronUp as ChevronUpIcon, FaChrome as ChromeIcon, MdClear as ClearIcon, BsClipboardCheck as ClipboardCheckIcon, HiOutlineClipboardCopy as ClipboardIcon, FiClock as ClockIcon, IoMdClose as CloseIcon, FaCloud as CloudIcon, IoCloudUploadOutline as CloudUploadIcon, GrServerCluster as ClusterIcon, LuCode as CodeIcon, FaCog as CogIcon, BsArrowsCollapse as CollapseIcon, BsLayoutThreeColumns as ColumnsIcon, BsChatLeft as CommentIcon, GoGitCommit as CommitIcon, GrCloudComputer as ComputeIcon, PiPlugsConnectedFill as ConnectIcon, FiCopy as CopyIcon, FaDollarSign as CostDashboardIcon, FaWandMagicSparkles as CustomizeIcon, FaDebian as DebianIcon, MdOutlineMoneyOff as DisableCostIcon, TbUserOff as DisableUserIcon, FiHardDrive as DiskIcon, LuSettings2 as DisplayIcon, FaDocker as DockerIcon, IoDocumentTextOutline as DocumentIcon, FiDownload as DownloadFileIcon, FaCloudDownloadAlt as DownloadIcon, MdDragHandle as DragHandleIcon, HiDuplicate as DuplicateIcon, FaEdge as EdgeIcon, FaEdit as EditIcon, VscLayoutSidebarLeft as EditorIcon, BsMortarboard as EducationIcon, MdOutlineAttachMoney as EnableCostIcon, TbUser as EnableUserIcon, TbWorldShare as EndpointIcon, ErrorCheckmark, BiError as ErrorIcon, LuLogs as EventsIcon, FaRunning as ExecuteWorkflow, FaExpand as ExpandIcon, BiExpandVertical as ExpandVerticalIcon, LuBraces as ExpressionIcon, LuExternalLink as ExternalLink, LuEye as EyeIcon, LuEyeOff as EyeOffIcon, HiMiniXCircle as FailIcon, IoHeart as FavoriteIcon, IoHeartOutline as FavoriteOutlineIcon, FaStar as FeaturedIcon, FiFile as FileIcon, FaFile as FileSolidIcon, FiFileText as FileTextIcon, BsFiles as FilesIcon, IoFileTrayFullOutline as FilesystemIcon, FaFilterCircleXmark as FilterClearIcon, FaFilter as FilterIcon, FaFirefoxBrowser as FirefoxIcon, FaFlask as FlaskIcon, FaRegFolder as FolderIcon, FaRegFolderOpen as FolderOpenIcon, FaFolder as FolderSolidIcon, LuFolderTree as FolderTreeIcon, GoSkip as ForbiddenIcon, GoRepoForked as ForkIcon, HiCog as GearIcon, FaCogs as GearsIcon, FaGithub as GitHubIcon, FaGitlab as GitLabIcon, FaGlobe as GlobeIcon, BsBank2 as GovernmentIcon, LuNetwork as GraphIcon, BsGrid as GridIcon, FiActivity as HealthMonitoringIcon, SiHelm as HelmIcon, FaEye as HiddenFalseIcon, FaEyeSlash as HiddenTrueIcon, FiRotateCcw as HistoryIcon, HiOutlineHome as HomeIcon, LuIdCard as IdCardIcon, FaRegFileImage as ImageIcon, FaImage as ImageSolidIcon, GiSpy as ImpersonateIcon, GrInbox as InboxIcon, IoInformationCircleOutline as InfoCircleIcon, FaInfoCircle as InfoIcon, BsLayers as InfrastructureLayersIcon, LuTextCursorInput as InputFormIcon, MdInstallDesktop as InstallIcon, FaLocationDot as IpAddressIcon, GoIssueOpened as IssueIcon, VscJson as JsonIcon, FaKey as KeyIcon, LuKeyboard as KeyboardIcon, SiKubernetes as KubernetesIcon, PiRectangleDashed as KubernetesNamespaceIcon, HiMiniLanguage as LanguageIcon, FaBalanceScale as LegalIcon, LuBadgeCheck as LicenseIcon, FaLink as LinkIcon, FaLinkedin as LinkedInIcon, FaLinux as LinuxIcon, BsListUl as ListViewIcon, LoaderIcon, FaLock as LockIcon, MdSmartphone as MFA, LuMail as MailIcon, BsGeoAlt as MapPinIcon, FaGlobeAmericas as MarketplaceIcon, LuMegaphone as MegaphoneIcon, BsThreeDotsVertical as MenuIcon, VscChromeMinimize as MinimizeIcon, BsDash as MinusIcon, LuBrainCircuit as MlIcon, BsCurrencyDollar as MoneyIcon, GrTasks as MonitorIcon, LuMoon as MoonIcon, BsThreeDots as MoreIcon, BsMusicNoteBeamed as MusicIcon, BiBellOff as MuteIcon, TbEdit as NewChatIcon, FaUpRightFromSquare as NewWindowIcon, FaRegCircle as NotRunningIcon, IoIosNotifications as NotificationFillIcon, FaInbox as NotificationInboxIcon, FaOpenid as OIDCIcon, BsOpenai as OpenAIIcon, PiArrowBendUpRightBold as OpenInNewGraphIcon, FaOpera as OperaIcon, BiBuildings as OrganizationIcon, FaRocket as PartnerIcon, FaKey as PasswordIcon, BiPause as PauseIcon, FaRegFilePdf as PdfIcon, FaFilePdf as PdfSolidIcon, BsTelephone as PhoneIcon, FaChartPie as PieChartIcon, BsStarFill as PinFilledIcon, BsStar as PinIcon, GoPlus as PlusOutlineIcon, FaPowerOff as PowerIcon, VscTerminalPowershell as PowershellIcon, FaPrint as PrintIcon, FaGlobeAmericas as PublishIcon, GoGitPullRequest as PullRequestIcon, FaQrcode as QRCodeIcon, MdPieChart as QuotaIcon, FaRedhat as RedHatIcon, BiRedo as RedoIcon, FaArrowsRotate as RefreshArrowsIcon, MdRefresh as RefreshIcon, MdReplay as ReplayIcon, FaLayerGroup as ResourceGroupIcon, FaUndoAlt as RetryIcon, FaRobot as RobotIcon, AiOutlineRollback as RollbackIcon, VscTerminalPowershell as RunWorkflowIcon, ImSpinner5 as RunningIcon, FaSafari as SafariIcon, FaSave as SaveIcon, FaList as SchedulerIcon, FaSearch as SearchIcon, BsSearch as SearchOutlineIcon, BsSend as SendIcon, HiServer as ServerIcon, IoSettingsOutline as SettingsIcon, PiShareBold as ShareIcon, FaUsers as SharingIcon, FaShieldAlt as ShieldAltIcon, BiSolidCheckShield as ShieldIcon, BsShieldSlash as ShieldOffIcon, LuShield as ShieldOutlineIcon, FaCompress as ShrinkIcon, TbLayoutSidebarRightCollapse as SidebarCloseIcon, TbLayoutSidebar as SidebarIcon, TbLayoutSidebarLeftCollapse as SidebarOpenIcon, GoSignOut as SignOutIcon, HiMiniMinusCircle as SkipIcon, FaSlack as SlackIcon, FaDesktop as SnapshotIcon, TiArrowSortedDown as SortDownIcon, TiArrowUnsorted as SortUnsortedIcon, TiArrowSortedUp as SortUpIcon, HiSparkles as SparklesIcon, VscSplitHorizontal as SplitIcon, LuSheet as SpreadsheetIcon, BiPlay as StartIcon, BsStopCircle as StopCircleIcon, BiStop as StopIcon, FaStop as StopSolidIcon, GrStorage as StorageIcon, TbWorldWww as SubdomainIcon, SuccessCheckmark, HiMiniCheckCircle as SuccessIcon, LuSun as SunIcon, FaSuse as SuseIcon, BsTag as TagIcon, FaTerminal as TerminalIcon, TbBrain as ThinkingIcon, FaTimes as TimesIcon, HiQuestionMarkCircle as TooltipIcon, BiSolidTrashAlt as TrashIcon, TbBuildingTunnel as TunnelIcon, FaUbuntu as UbuntuIcon, BiUndo as UndoIcon, IoHeartDislike as UnfavoriteIcon, FaUnlink as UnlinkIcon, BiBell as UnmuteIcon, FiUpload as UploadIcon, FaQuestionCircle as UserGuideIcon, FaUser as UserIcon, BsTerminalFill as UserWorkspaceFillIcon, BsTerminal as UserWorkspaceIcon, FaUsers as UsersIcon, GoVideo as VideoIcon, IoWarningOutline as WarningIcon, FaExclamationTriangle as WarningTriangleIcon, FaWindows as WindowsIcon, FiX as XIcon, LuX as XStrokeIcon, FaXTwitter as XTwitterIcon, FiZap as ZapIcon, BsFileEarmarkZip as ZipIcon, LuZoomIn as ZoomInIcon, LuZoomOut as ZoomOutIcon };
package/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@ export { default as MultiSelectDropdown } from './components/MultiSelect.js';
31
31
  export { Overview } from './components/Overview.js';
32
32
  export { BreadcrumbsActionButton, BreadcrumbsRightAction, BreadcrumbsTitleAction, HeaderActionMenu, HeaderAddButton, HeaderEditButton, HeaderRowMenu, headerActionButtonClasses, PageHeader, type PageHeaderBreadcrumb, type PageHeaderCrumb, } from './components/PageHeader.js';
33
33
  export { Pagination } from './components/Pagination.js';
34
- export { type PersistedStateHook, type RunFileResult, type UIData, type UILinkComponent, type UINavigation, type UINotify, UIProvider, type UISlots, type UIStrings, type UIToastId, type UIToastOptions, type UIToastUpdate, useNavigation, useNotify, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowEngine, useWorkflowEngineLoader, type WorkflowEngineSource, } from './components/Provider.js';
34
+ export { type PersistedStateHook, type RunFileResult, type UIData, type UILinkComponent, type UINavigation, type UINotify, UIProvider, type UISlots, type UIStrings, type UIToastId, type UIToastOptions, type UIToastUpdate, useNavigation, useNotify, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader, type WorkflowEngineSource, type WorkflowJsonRef, } from './components/Provider.js';
35
35
  export { RequiredMark } from './components/RequiredMark.js';
36
36
  export { useRelativeTime } from './components/relativeTime.js';
37
37
  export { default as SectionHeader } from './components/SectionHeader.js';
@@ -48,5 +48,6 @@ export { CompactTable, Table } from './components/Table.js';
48
48
  export { Toggle } from './components/Toggle.js';
49
49
  export { formatTooltipContent, GlobalTooltip, TOOLTIP_ID, TooltipInfo, truncationTooltipProps, } from './components/Tooltip.js';
50
50
  export { useCssIsDark } from './components/useCssIsDark.js';
51
+ export type { EditRefusalReason, FieldPatch, GraphEdit, GraphEditResult, GraphEditState, GraphLayout, GraphPosition, GraphSlot, InputEdit, InputPath, LintFix, NeedRef, StepRef, WorkflowAction, WorkflowActionInput, WorkflowEditing, WorkflowLintContext, WorkflowLintProblem, } from './editing.js';
51
52
  export type { EngineJob, EngineStep, EvaluateOptions, ExpansionKeys, LogCommand, LogSegment, MatrixGroup, ProcessedLogLine, RunStatus, WorkflowEngine, WorkflowVariable, WorkflowVariables, } from './engine.js';
52
53
  export * from './theme/index.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { UIProvider, useNavigation, useNotify, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowEngine, useWorkflowEngineLoader } from "./components/Provider.js";
1
+ import { UIProvider, useNavigation, useNotify, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader } from "./components/Provider.js";
2
2
  import { GlobalTooltip, TOOLTIP_ID, TooltipInfo, formatTooltipContent, truncationTooltipProps } from "./components/Tooltip.js";
3
3
  import { AddMenu } from "./components/AddMenu.js";
4
4
  import { Avatar, avatarInitials } from "./components/Avatar.js";
@@ -46,4 +46,4 @@ import { CompactTable, Table } from "./components/Table.js";
46
46
  import { Toggle } from "./components/Toggle.js";
47
47
  import { useCssIsDark } from "./components/useCssIsDark.js";
48
48
  import { DEFAULT_PRESET, THEME_PRESETS, THEME_TOKENS, applyTheme, contrastRatio, deriveTheme, isDarkColor } from "./theme/index.js";
49
- export { AddMenu, Avatar, BareModal, BreadcrumbProvider, BreadcrumbsActionButton, BreadcrumbsRightAction, BreadcrumbsTitleAction, Button, CREATE_MODAL_SELECT_FILTER_THRESHOLD, Callout, Card, CardHeader, CompactTable, ConfirmModal, ControlledCollapsiblePanel, CopyCodeBlock, CopyToClipboard, CreateModal, CreateModalAutocompleteField, CreateModalField, CreateModalSelect, CreateModalSwitch, CreateModalTextarea, CustomListbox, DEFAULT_PRESET, DescriptionList, DescriptionListItem, Dropdown, DropdownCaret, EmptyState, Filter, FilterPill, GlobalTooltip, HeaderActionMenu, HeaderAddButton, HeaderEditButton, HeaderRowMenu, IconButton, Indicator, Input, LetterBadge, Loader, Markdown, MaybeCollapsible, MethodButton, MultiSelectDropdown, Overview, PageHeader, Pagination, RequiredMark, SectionHeader, SegmentedControl, SettingModeOption, SettingRow, SettingSection, SettingsCard, SettingsGroup, Sort, StatusBadge, StatusDot, SwitchToggle, SwitchToggleSmall, THEME_PRESETS, THEME_TOKENS, TOOLTIP_ID, Table, Textarea, Toggle, TooltipInfo, UIProvider, UncontrolledCollapsiblePanel, applyTheme, avatarInitials, contrastRatio, dangerButtonClasses, deriveTheme, filterOption, flattenOptions, formatTooltipContent, ghostButtonClasses, headerActionButtonClasses, inputClasses, isCategory, isDarkColor, isOption, modalPanelClasses, primaryButtonClasses, statusTextClass, toggleSetMember, truncationTooltipProps, useBreadcrumb, useClearBreadcrumbs, useCssIsDark, useHideBreadcrumbs, useNavigation, useNotify, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRelativeTime, useRunFile, useSetBreadcrumbs, useSetDefaultBreadcrumbs, useSlots, useStrings, useWorkflowEngine, useWorkflowEngineLoader };
49
+ export { AddMenu, Avatar, BareModal, BreadcrumbProvider, BreadcrumbsActionButton, BreadcrumbsRightAction, BreadcrumbsTitleAction, Button, CREATE_MODAL_SELECT_FILTER_THRESHOLD, Callout, Card, CardHeader, CompactTable, ConfirmModal, ControlledCollapsiblePanel, CopyCodeBlock, CopyToClipboard, CreateModal, CreateModalAutocompleteField, CreateModalField, CreateModalSelect, CreateModalSwitch, CreateModalTextarea, CustomListbox, DEFAULT_PRESET, DescriptionList, DescriptionListItem, Dropdown, DropdownCaret, EmptyState, Filter, FilterPill, GlobalTooltip, HeaderActionMenu, HeaderAddButton, HeaderEditButton, HeaderRowMenu, IconButton, Indicator, Input, LetterBadge, Loader, Markdown, MaybeCollapsible, MethodButton, MultiSelectDropdown, Overview, PageHeader, Pagination, RequiredMark, SectionHeader, SegmentedControl, SettingModeOption, SettingRow, SettingSection, SettingsCard, SettingsGroup, Sort, StatusBadge, StatusDot, SwitchToggle, SwitchToggleSmall, THEME_PRESETS, THEME_TOKENS, TOOLTIP_ID, Table, Textarea, Toggle, TooltipInfo, UIProvider, UncontrolledCollapsiblePanel, applyTheme, avatarInitials, contrastRatio, dangerButtonClasses, deriveTheme, filterOption, flattenOptions, formatTooltipContent, ghostButtonClasses, headerActionButtonClasses, inputClasses, isCategory, isDarkColor, isOption, modalPanelClasses, primaryButtonClasses, statusTextClass, toggleSetMember, truncationTooltipProps, useBreadcrumb, useClearBreadcrumbs, useCssIsDark, useHideBreadcrumbs, useNavigation, useNotify, useOptionalWorkflowEngine, usePersistedState, useProvisionCorsRules, useRelativeTime, useRunFile, useSetBreadcrumbs, useSetDefaultBreadcrumbs, useSlots, useStrings, useWorkflowActions, useWorkflowEditing, useWorkflowEngine, useWorkflowEngineLoader };
@@ -11,6 +11,8 @@ export interface ToolbarAction {
11
11
  enabledTooltip?: string;
12
12
  disabledTooltip?: string | undefined;
13
13
  hidden?: boolean;
14
+ /** Makes the action a toggle: filled while on, outlined while off. */
15
+ active?: boolean | undefined;
14
16
  }
15
17
  /** A pre-rendered element (e.g. a button component that owns its modal). */
16
18
  interface ToolbarElement {
@@ -1,5 +1,6 @@
1
1
  import { useLink, useStrings } from "../components/Provider.js";
2
2
  import { BsThreeDotsVertical } from "../icons/bs/BsThreeDotsVertical.js";
3
+ import { FaCheck } from "../icons/fa/FaCheck.js";
3
4
  import { TOOLTIP_ID } from "../components/Tooltip.js";
4
5
  import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
5
6
  import cx from "classnames";
@@ -23,7 +24,9 @@ function ToolbarButton({ action }) {
23
24
  const inOverflowMenu = useContext(OverflowMenuContext);
24
25
  const Link = useLink();
25
26
  if (inOverflowMenu) return /* @__PURE__ */ jsx(OverflowRow, { item: action });
26
- const className = cx("inline-flex items-center gap-x-0.5 h-9 px-2 rounded-md text-[13.5px] uppercase font-semibold transition-colors whitespace-nowrap", "bg-(--theme-element) text-(--theme-element-text)", action.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-(--theme-element-hover)");
27
+ const off = action.active === false;
28
+ const className = cx("inline-flex items-center gap-x-0.5 h-9 px-2 rounded-md text-[13.5px] uppercase font-semibold transition-colors whitespace-nowrap", off ? "border theme-border theme-muted-text" : "bg-(--theme-element) text-(--theme-element-text)", action.disabled ? "opacity-50 cursor-not-allowed" : off ? "cursor-pointer hover:theme-hover" : "cursor-pointer hover:bg-(--theme-element-hover)");
29
+ const pressed = action.active === void 0 ? {} : { "aria-pressed": action.active };
27
30
  const tooltipProps = tipProps(action.disabled ? action.disabledTooltip : action.enabledTooltip, "bottom");
28
31
  const Icon = action.icon;
29
32
  const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
@@ -43,6 +46,7 @@ function ToolbarButton({ action }) {
43
46
  type: "button",
44
47
  disabled: true,
45
48
  className,
49
+ ...pressed,
46
50
  children: content
47
51
  })
48
52
  });
@@ -50,6 +54,7 @@ function ToolbarButton({ action }) {
50
54
  type: "button",
51
55
  onClick: action.onClick,
52
56
  className,
57
+ ...pressed,
53
58
  ...tooltipProps,
54
59
  children: content
55
60
  });
@@ -57,17 +62,24 @@ function ToolbarButton({ action }) {
57
62
  /** A single overflowed item rendered as a full-width row inside the `…` menu. */
58
63
  function OverflowRow({ item }) {
59
64
  const Link = useLink();
65
+ const { list: t } = useStrings();
60
66
  const Icon = item.icon;
61
67
  const className = cx("flex w-full items-center gap-x-1 px-4 py-2 text-[13px] uppercase font-semibold link hover:theme-hover", item.disabled && "opacity-50 cursor-not-allowed");
62
68
  const tooltipProps = tipProps(item.disabled ? item.disabledTooltip : item.enabledTooltip, "left");
63
- const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
64
- className: "w-5 h-6 flex items-center",
65
- children: /* @__PURE__ */ jsx(Icon, { className: cx(item.iconClassName) })
66
- }), item.label] });
69
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
70
+ /* @__PURE__ */ jsx("div", {
71
+ className: "w-5 h-6 flex items-center",
72
+ children: /* @__PURE__ */ jsx(Icon, { className: cx(item.iconClassName) })
73
+ }),
74
+ item.label,
75
+ item.active && /* @__PURE__ */ jsx(FaCheck, { className: "ml-auto h-4 w-4 opacity-80" })
76
+ ] });
77
+ const named = item.active === void 0 ? {} : { "aria-label": t.toggleState(item.label, item.active) };
67
78
  if (item.href && !item.disabled) return /* @__PURE__ */ jsx(MenuItem, {
68
79
  as: Link,
69
80
  to: item.href,
70
81
  className,
82
+ ...named,
71
83
  ...tooltipProps,
72
84
  children: content
73
85
  });
@@ -77,6 +89,7 @@ function OverflowRow({ item }) {
77
89
  onClick: item.onClick,
78
90
  disabled: item.disabled ?? false,
79
91
  className,
92
+ ...named,
80
93
  ...tooltipProps,
81
94
  children: content
82
95
  });
@@ -24,15 +24,24 @@ export type RowMenuItem = {
24
24
  text: string;
25
25
  label: string;
26
26
  };
27
+ /** More text a menu's search matches, beside the label. */
28
+ keywords?: string;
27
29
  } | {
28
30
  kind: 'submenu';
29
31
  label: string;
30
32
  icon?: ReactNode;
31
33
  items: RowMenuItem[];
34
+ search?: MenuSearch | undefined;
32
35
  } | {
33
36
  kind: 'divider';
34
37
  };
35
- export type OpenMenu = (x: number, y: number, items: RowMenuItem[], onClose?: () => void) => void;
38
+ /** A field atop a menu that narrows it, submenus included, to the items it matches. */
39
+ export interface MenuSearch {
40
+ placeholder: string;
41
+ /** Shown when nothing matches. */
42
+ empty: string;
43
+ }
44
+ export type OpenMenu = (x: number, y: number, items: RowMenuItem[], onClose?: () => void, search?: MenuSearch) => void;
36
45
  /** The shared shape every entity action hook's per-row actions boil down to.
37
46
  * Each hook's bespoke `*RowAction` type is structurally assignable to this. */
38
47
  export interface RowAction {
@@ -14,7 +14,7 @@ import { keyedByContent } from "../components/keys.js";
14
14
  import { TOOLTIP_ID } from "../components/Tooltip.js";
15
15
  import cx from "classnames";
16
16
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
17
- import { jsx, jsxs } from "react/jsx-runtime";
17
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
18
18
  import { createPortal } from "react-dom";
19
19
  //#region src/list/RowContextMenu.tsx
20
20
  /** Converts a single row action to a menu item: a `to` makes it a link, otherwise an action. */
@@ -74,14 +74,15 @@ function assembleRowMenu({ lead = [], actions, exclude, order, trailing = ["dele
74
74
  function useRowMenu(zClassName = "z-50") {
75
75
  const [menu, setMenu] = useState(null);
76
76
  const onCloseRef = useRef(void 0);
77
- const openMenu = useCallback((x, y, items, onClose) => {
77
+ const openMenu = useCallback((x, y, items, onClose, search) => {
78
78
  if (items.length > 0) {
79
79
  onCloseRef.current?.();
80
80
  onCloseRef.current = onClose;
81
81
  setMenu({
82
82
  x,
83
83
  y,
84
- items
84
+ items,
85
+ search
85
86
  });
86
87
  }
87
88
  }, []);
@@ -104,9 +105,12 @@ function useRowMenuActive(openMenu) {
104
105
  const [active, setActive] = useState(false);
105
106
  return {
106
107
  active,
107
- openMenu: useCallback((x, y, items) => {
108
+ openMenu: useCallback((x, y, items, onClose, search) => {
108
109
  setActive(true);
109
- openMenu(x, y, items, () => setActive(false));
110
+ openMenu(x, y, items, () => {
111
+ setActive(false);
112
+ onClose?.();
113
+ }, search);
110
114
  }, [openMenu])
111
115
  };
112
116
  }
@@ -120,22 +124,46 @@ function rowContextMenuProps(openMenu, items) {
120
124
  function RowContextMenu({ state, onClose, zClassName }) {
121
125
  const ref = useRef(null);
122
126
  const [pos, setPos] = useState(null);
127
+ const opener = useRef(null);
128
+ const wasOpen = useRef(false);
123
129
  useLayoutEffect(() => {
124
- if (!state || !ref.current) {
130
+ const menu = ref.current;
131
+ if (!state || !menu) {
125
132
  setPos(null);
133
+ wasOpen.current = false;
126
134
  return;
127
135
  }
128
- const { width, height } = ref.current.getBoundingClientRect();
129
- const pad = 8;
130
- const top = height > window.innerHeight - pad - state.y && state.y - height - pad >= 0 ? state.y - height : Math.min(state.y, window.innerHeight - height - pad);
136
+ if (!wasOpen.current) {
137
+ opener.current = document.activeElement;
138
+ wasOpen.current = true;
139
+ }
140
+ const { width, height } = menu.getBoundingClientRect();
141
+ const pad = MENU_EDGE;
142
+ const openUp = height > window.innerHeight - pad - state.y && state.y - height - pad >= 0;
143
+ const top = Math.max(pad, openUp ? state.y - height : Math.min(state.y, window.innerHeight - height - pad));
131
144
  setPos({
132
145
  left: Math.max(pad, Math.min(state.x, window.innerWidth - width - pad)),
133
- top: Math.max(pad, top)
146
+ top,
147
+ maxHeight: (openUp ? state.y : window.innerHeight - pad) - top
134
148
  });
135
149
  }, [state]);
150
+ const placed = pos !== null;
151
+ useEffect(() => {
152
+ const menu = ref.current;
153
+ if (!placed || !menu) return;
154
+ const from = opener.current;
155
+ const target = menu.querySelector(":scope > div > input[type=\"search\"]") ?? (focusVisible(from) ? menu.querySelector(MENU_ITEMS) : null);
156
+ if (!target) return;
157
+ target.focus({ preventScroll: true });
158
+ return () => {
159
+ if (from instanceof HTMLElement && document.activeElement === document.body) from.focus({ preventScroll: true });
160
+ };
161
+ }, [placed, state]);
136
162
  useEffect(() => {
137
163
  if (!state) return;
138
- const close = () => onClose();
164
+ const close = (e) => {
165
+ if (!(e.target instanceof Node && ref.current?.contains(e.target))) onClose();
166
+ };
139
167
  const onKey = (e) => {
140
168
  if (e.key === "Escape") onClose();
141
169
  };
@@ -178,23 +206,116 @@ function RowContextMenu({ state, onClose, zClassName }) {
178
206
  children: /* @__PURE__ */ jsx("div", {
179
207
  ref,
180
208
  role: "menu",
181
- className: "absolute min-w-44 rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) py-1 shadow-lg backdrop-blur-xl",
209
+ className: "absolute flex min-w-44 flex-col rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) py-1 shadow-lg backdrop-blur-xl",
182
210
  style: {
183
211
  left: pos?.left ?? state.x,
184
212
  top: pos?.top ?? state.y,
213
+ maxHeight: state.search ? pos?.maxHeight : void 0,
185
214
  visibility: pos ? "visible" : "hidden"
186
215
  },
216
+ onKeyDown: (e) => {
217
+ const step = {
218
+ ArrowDown: 1,
219
+ ArrowUp: -1
220
+ }[e.key];
221
+ if (!step || e.defaultPrevented || !ref.current) return;
222
+ e.preventDefault();
223
+ const items = [...ref.current.querySelectorAll(MENU_ITEMS)];
224
+ const at = items.indexOf(document.activeElement);
225
+ focusItem(items[((at < 0 ? step > 0 ? 0 : items.length - 1 : at + step) + items.length) % items.length]);
226
+ },
187
227
  children: /* @__PURE__ */ jsx(MenuItemList, {
188
228
  items: state.items,
229
+ search: state.search,
189
230
  onClose,
190
231
  side
191
232
  })
192
233
  })
193
234
  }), document.body);
194
235
  }
236
+ var MENU_EDGE = 8;
237
+ function focusItem(item) {
238
+ item?.focus({ preventScroll: true });
239
+ item?.scrollIntoView?.({ block: "nearest" });
240
+ }
241
+ function SubmenuPanel({ side, panelRef, searchable, children }) {
242
+ const [place, setPlace] = useState(null);
243
+ useLayoutEffect(() => {
244
+ const rect = panelRef.current?.getBoundingClientRect();
245
+ if (rect) {
246
+ const bottom = window.innerHeight - MENU_EDGE;
247
+ const lift = Math.max(0, Math.min(rect.bottom - bottom, rect.top - MENU_EDGE));
248
+ setPlace({
249
+ lift,
250
+ maxHeight: bottom - (rect.top - lift)
251
+ });
252
+ }
253
+ }, [panelRef]);
254
+ return /* @__PURE__ */ jsx("div", {
255
+ ref: panelRef,
256
+ className: cx("absolute -top-1 z-10 flex min-w-44 flex-col rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) py-1 shadow-lg", side === "left" ? "right-full" : "left-full"),
257
+ style: place ? {
258
+ ...searchable ? { maxHeight: place.maxHeight } : {},
259
+ ...place.lift > 0 ? { transform: `translateY(-${place.lift}px)` } : {}
260
+ } : void 0,
261
+ children
262
+ });
263
+ }
264
+ var MENU_ITEMS = "button:not([disabled]), a[href]";
265
+ function focusVisible(element) {
266
+ try {
267
+ return !!element?.matches(":focus-visible");
268
+ } catch {
269
+ return false;
270
+ }
271
+ }
195
272
  var MENU_ITEM_CLASSES = "flex w-full items-center gap-2.5 px-3 py-1.5 text-left text-[13px] hover:bg-(--theme-muted-panel-bg) transition-colors cursor-pointer [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0";
196
- function MenuItemList({ items, onClose, side }) {
197
- return keyedByContent(items, (it) => it.kind === "divider" ? "divider" : it.label).map(({ key, item }) => item.kind === "divider" ? /* @__PURE__ */ jsx("div", {
273
+ function matchesSearch(item, needle) {
274
+ const keywords = item.kind === "action" ? item.keywords ?? "" : "";
275
+ return `${item.label} ${keywords}`.toLowerCase().includes(needle);
276
+ }
277
+ function searchMatches(items, needle) {
278
+ const found = /* @__PURE__ */ new Map();
279
+ const walk = (list) => {
280
+ for (const item of list) if (item.kind === "submenu") walk(item.items);
281
+ else if (item.kind !== "divider" && !found.has(item.label) && matchesSearch(item, needle)) found.set(item.label, item);
282
+ };
283
+ walk(items);
284
+ return [...found.values()];
285
+ }
286
+ function MenuSearchField({ search, query, onQuery, onEnter }) {
287
+ return /* @__PURE__ */ jsx("div", {
288
+ className: "px-2 pt-0.5 pb-1",
289
+ children: /* @__PURE__ */ jsx("input", {
290
+ type: "search",
291
+ "aria-label": search.placeholder,
292
+ placeholder: search.placeholder,
293
+ value: query,
294
+ onChange: (e) => onQuery(e.target.value),
295
+ onKeyDown: (e) => {
296
+ if (e.key === "Enter") {
297
+ e.preventDefault();
298
+ onEnter();
299
+ } else if (e.key === "ArrowDown") {
300
+ e.preventDefault();
301
+ focusItem(e.currentTarget.parentElement?.parentElement?.querySelector(MENU_ITEMS));
302
+ }
303
+ },
304
+ className: "w-full rounded-md border border-(--theme-border) bg-(--theme-muted-panel-bg) px-2 py-1 text-[13px] text-(--theme-app) placeholder:text-(--theme-muted-text-color) focus:border-(--theme-element) focus:outline-none"
305
+ })
306
+ });
307
+ }
308
+ function MenuItemList({ items, search, onClose, side }) {
309
+ const [query, setQuery] = useState("");
310
+ const needle = query.trim().toLowerCase();
311
+ const searching = !!search && !!needle;
312
+ const shown = searching ? searchMatches(items, needle) : items;
313
+ const run = useRunItem(onClose);
314
+ const pickFirst = () => {
315
+ const first = shown.find((item) => item.kind === "action" && !item.disabled);
316
+ if (first?.kind === "action") run(first);
317
+ };
318
+ const rows = keyedByContent(shown, (it) => it.kind === "divider" ? "divider" : it.label).map(({ key, item }) => item.kind === "divider" ? /* @__PURE__ */ jsx("div", {
198
319
  "aria-hidden": "true",
199
320
  className: "my-1 h-px bg-(--theme-border)"
200
321
  }, key) : /* @__PURE__ */ jsx(MenuRow, {
@@ -202,13 +323,30 @@ function MenuItemList({ items, onClose, side }) {
202
323
  onClose,
203
324
  side
204
325
  }, key));
326
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
327
+ search && /* @__PURE__ */ jsx(MenuSearchField, {
328
+ search,
329
+ query,
330
+ onQuery: setQuery,
331
+ onEnter: pickFirst
332
+ }),
333
+ searching ? /* @__PURE__ */ jsx("div", {
334
+ className: "max-h-[min(20rem,60vh)] min-h-0 overflow-y-auto",
335
+ children: rows
336
+ }) : rows,
337
+ searching && shown.length === 0 && /* @__PURE__ */ jsx("div", {
338
+ className: "px-3 py-1.5 text-[13px] text-(--theme-muted-text-color)",
339
+ children: search.empty
340
+ })
341
+ ] });
205
342
  }
206
343
  function MenuRow({ item, onClose, side }) {
207
344
  const Link = useLink();
208
- const notify = useNotify();
209
- const { list: t } = useStrings();
345
+ const run = useRunItem(onClose);
210
346
  const [openSub, setOpenSub] = useState(false);
211
347
  const closeTimer = useRef(void 0);
348
+ const panel = useRef(null);
349
+ const hovered = useRef(false);
212
350
  if (item.kind === "submenu") {
213
351
  const open = () => {
214
352
  clearTimeout(closeTimer.current);
@@ -220,10 +358,19 @@ function MenuRow({ item, onClose, side }) {
220
358
  return /* @__PURE__ */ jsxs("div", {
221
359
  className: "relative",
222
360
  role: "none",
223
- onMouseEnter: open,
224
- onMouseLeave: close,
361
+ onMouseEnter: () => {
362
+ hovered.current = true;
363
+ open();
364
+ },
365
+ onMouseLeave: () => {
366
+ hovered.current = false;
367
+ if (!panel.current?.contains(document.activeElement)) close();
368
+ },
225
369
  onFocus: open,
226
- onBlur: close,
370
+ onBlur: (e) => {
371
+ const to = e.relatedTarget;
372
+ if (!e.currentTarget.contains(to) && (to !== null || !hovered.current)) close();
373
+ },
227
374
  children: [/* @__PURE__ */ jsxs("button", {
228
375
  type: "button",
229
376
  "aria-expanded": openSub,
@@ -234,10 +381,13 @@ function MenuRow({ item, onClose, side }) {
234
381
  className: "flex items-center gap-2.5",
235
382
  children: [item.icon, item.label]
236
383
  }), /* @__PURE__ */ jsx(LuChevronRight, { className: "h-3 w-3 shrink-0 opacity-60" })]
237
- }), openSub && /* @__PURE__ */ jsx("div", {
238
- className: cx("absolute -top-1 z-10 min-w-44 rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) py-1 shadow-lg", side === "left" ? "right-full" : "left-full"),
384
+ }), openSub && /* @__PURE__ */ jsx(SubmenuPanel, {
385
+ side,
386
+ panelRef: panel,
387
+ searchable: !!item.search,
239
388
  children: /* @__PURE__ */ jsx(MenuItemList, {
240
389
  items: item.items,
390
+ search: item.search,
241
391
  onClose,
242
392
  side
243
393
  })
@@ -267,15 +417,7 @@ function MenuRow({ item, onClose, side }) {
267
417
  "data-tooltip-id": TOOLTIP_ID,
268
418
  "data-tooltip-content": item.tooltip
269
419
  } : {},
270
- onClick: () => {
271
- if (item.disabled) return;
272
- if (item.copy) {
273
- const { text, label } = item.copy;
274
- navigator.clipboard?.writeText(text).then(() => notify.success(t.copied(label)), () => notify.error(t.couldntCopy(label)));
275
- }
276
- item.onSelect?.();
277
- onClose();
278
- },
420
+ onClick: () => run(item),
279
421
  className: cx(MENU_ITEM_CLASSES, item.destructive ? "text-red-500" : "text-(--theme-app)", item.disabled && "opacity-40 cursor-not-allowed hover:bg-transparent"),
280
422
  children: [
281
423
  item.icon,
@@ -284,6 +426,19 @@ function MenuRow({ item, onClose, side }) {
284
426
  ]
285
427
  });
286
428
  }
429
+ function useRunItem(onClose) {
430
+ const notify = useNotify();
431
+ const { list: t } = useStrings();
432
+ return (item) => {
433
+ if (item.disabled) return;
434
+ if (item.copy) {
435
+ const { text, label } = item.copy;
436
+ navigator.clipboard?.writeText(text).then(() => notify.success(t.copied(label)), () => notify.error(t.couldntCopy(label)));
437
+ }
438
+ item.onSelect?.();
439
+ onClose();
440
+ };
441
+ }
287
442
  /** Returns a builder for the Copy submenu, labeled from the provider's strings. */
288
443
  function useCopySubmenu() {
289
444
  const { list: t } = useStrings();