UNPKG

@fidely-ui/react

Version:

Fidely UI is a modern, beautifully crafted React design system powered by Ark UI and Panda CSS, delivering accessible and themeable components for building exceptional web apps

49 lines (48 loc) 2.52 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import { cx } from '@fidely-ui/styled-system/css'; import { commandInput } from '@fidely-ui/styled-system/recipes'; import { Group } from '../group/index'; import { Kbd } from '../kbd/index'; import { Flex } from '../flex/index'; import { Text } from '../text/index'; import { isMobileDevice } from '../../utils/is-mobile-device'; import { FiSearch } from '../icons/FiSearch'; export const CommandInput = React.forwardRef(function CommandInput(props, ref) { const { shortcut, onOpen, placeholder = 'Search...', leftElement, className, ...rest } = props; const slotStyles = commandInput(); const [isMobile, setIsMobile] = React.useState(false); const [resolvedShortcut, setResolvedShortcut] = React.useState(null); React.useEffect(() => { const mobile = isMobileDevice(); setIsMobile(mobile); if (!mobile) { const isMac = /Mac|iPod|iPhone|iPad/.test(navigator.userAgent); setResolvedShortcut(shortcut ?? (isMac ? '⌘ + K' : 'Ctrl + K')); } }, [shortcut]); React.useEffect(() => { if (isMobile || !resolvedShortcut) return; const parts = resolvedShortcut.split('+').map((p) => p.trim().toLowerCase()); const handleKeyDown = (e) => { const pressed = []; if (e.metaKey) pressed.push('⌘'); if (e.ctrlKey) pressed.push('ctrl'); pressed.push(e.key.toLowerCase()); const combo = pressed.join(' '); const target = parts.join(' ').toLowerCase(); if (combo === target) { e.preventDefault(); onOpen?.(); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [resolvedShortcut, onOpen, isMobile]); return (_jsxs(Group, { as: "button", ref: ref, onClick: onOpen, "aria-haspopup": "dialog", "aria-expanded": false, className: cx(slotStyles, className), ...rest, children: [_jsxs(Flex, { alignItems: "center", gap: "2", children: [leftElement ?? _jsx(FiSearch, {}), _jsx(Text, { color: "fg.muted", children: placeholder })] }), !isMobile && resolvedShortcut ? (_jsx(Flex, { gap: "1", children: resolvedShortcut.split('+').map((key, i) => (_jsx(Kbd, { children: key.trim() }, i))) })) : null] })); }); CommandInput.displayName = 'CommandInput';