@devalok/shilp-sutra 0.52.0 → 0.54.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.
- package/AGENTS.md +7 -1
- package/BREAKING.json +29 -0
- package/MIGRATION.md +61 -0
- package/dist/_chunks/motion-provider.js +7 -6
- package/dist/_chunks/motion-provider.js.map +1 -1
- package/dist/_chunks/success.js +53 -53
- package/dist/ai/command-bar.js +158 -158
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.js +5 -5
- package/dist/composed/avatar-group.d.ts +11 -9
- package/dist/composed/avatar-group.d.ts.map +1 -1
- package/dist/composed/avatar-group.js +108 -140
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.d.ts +19 -11
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +81 -110
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.js +17 -17
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/error-boundary.d.ts +15 -3
- package/dist/composed/error-boundary.d.ts.map +1 -1
- package/dist/composed/error-boundary.js +43 -26
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/loading-skeleton.d.ts +2 -0
- package/dist/composed/loading-skeleton.d.ts.map +1 -1
- package/dist/composed/loading-skeleton.js +79 -56
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/master-detail.d.ts +21 -8
- package/dist/composed/master-detail.d.ts.map +1 -1
- package/dist/composed/master-detail.js +91 -77
- package/dist/composed/master-detail.js.map +1 -1
- package/dist/composed/page-skeletons.d.ts +6 -0
- package/dist/composed/page-skeletons.d.ts.map +1 -1
- package/dist/composed/page-skeletons.js +93 -71
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/composed/priority-indicator.d.ts +15 -6
- package/dist/composed/priority-indicator.d.ts.map +1 -1
- package/dist/composed/priority-indicator.js +37 -88
- package/dist/composed/priority-indicator.js.map +1 -1
- package/dist/composed/schedule-view.d.ts +17 -2
- package/dist/composed/schedule-view.d.ts.map +1 -1
- package/dist/composed/schedule-view.js +163 -64
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/motion/motion-provider.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.d.ts +32 -6
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +156 -129
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/index.d.ts +5 -3
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +2 -3
- package/dist/shell/notification-preferences.d.ts.map +1 -1
- package/dist/shell/notification-preferences.js +2 -0
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/tokens/primitives.css +6 -2
- package/dist/tokens/utilities.css +6 -0
- package/dist/ui/autocomplete.d.ts +34 -32
- package/dist/ui/autocomplete.d.ts.map +1 -1
- package/dist/ui/autocomplete.js +115 -110
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/combobox.d.ts +1 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +133 -128
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/file-upload.d.ts.map +1 -1
- package/dist/ui/file-upload.js +124 -138
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/form.d.ts +7 -0
- package/dist/ui/form.d.ts.map +1 -1
- package/dist/ui/form.js +4 -2
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/icon-button.d.ts +2 -1
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js +1 -1
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/index.js +30 -30
- package/dist/ui/label.d.ts.map +1 -1
- package/dist/ui/label.js +7 -6
- package/dist/ui/label.js.map +1 -1
- package/dist/ui/search-input.js +4 -4
- package/dist/ui/sidebar.js +7 -7
- package/dist/ui/spinner.d.ts.map +1 -1
- package/dist/ui/spinner.js +50 -44
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/switch.d.ts.map +1 -1
- package/dist/ui/switch.js +24 -24
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/table.js +1 -1
- package/dist/ui/table.js.map +1 -1
- package/docs/components/composed/bulk-action-bar.md +9 -3
- package/docs/components/composed/error-boundary.md +18 -2
- package/docs/components/composed/master-detail.md +12 -2
- package/docs/components/composed/page-skeletons.md +2 -2
- package/docs/components/composed/priority-indicator.md +22 -11
- package/docs/components/composed/rich-chat-input.md +18 -6
- package/docs/components/composed/schedule-view.md +20 -5
- package/docs/components/composed/simple-tooltip.md +1 -1
- package/docs/components/shell/app-command-palette.md +2 -1
- package/docs/components/shell/bottom-navbar.md +28 -9
- package/docs/components/shell/command-registry.md +2 -2
- package/docs/components/shell/link-context.md +2 -2
- package/docs/components/shell/top-bar.md +1 -1
- package/docs/components/ui/autocomplete.md +26 -10
- package/docs/components/ui/search-input.md +2 -2
- package/docs/components/ui/slider.md +2 -2
- package/docs/components/ui/split-button.md +3 -3
- package/llms.txt +2 -2
- package/make-kit/Guidelines.md +1 -1
- package/make-kit/components/overview.md +2 -2
- package/make-kit/foundations/surfaces.md +1 -1
- package/mcp-manifest.json +581 -172
- package/package.json +1 -6
- package/skill/SKILL.md +1 -1
- package/skill/chat-skill/README.md +18 -0
- package/skill/chat-skill/SKILL.md +78 -0
- package/skill/chat-skill/chatgpt-instructions.md +26 -0
- package/skill/chat-skill/gemini-instructions.md +25 -0
- package/skill/references/components.md +2 -2
- package/dist/shell/sidebar.d.ts +0 -113
- package/dist/shell/sidebar.d.ts.map +0 -1
- package/dist/shell/sidebar.js +0 -293
- package/dist/shell/sidebar.js.map +0 -1
- package/docs/components/shell/sidebar.md +0 -103
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-bar.js","names":[],"sources":["../../src/ai/command-bar.tsx"],"sourcesContent":["'use client'\n\n/**\n * CommandBar -- Unified AI command interface.\n *\n * Three variants:\n * - hero: Full-featured inline bar with greeting, hints, placeholder rotation\n * - inline: Compact inline bar for embedding in panels/toolbars\n * - floating: Modal overlay (same pattern as CommandPalette) with global keybinding\n *\n * Supports both command-palette filtering (when `groups` provided) and\n * AI natural-language submission via `onSubmit`.\n */\nimport {\n IconArrowDown,\n IconArrowUp,\n IconCornerDownLeft,\n IconLoader2,\n IconSearch,\n IconX,\n} from '@tabler/icons-react'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport type { CommandGroup, CommandItem } from '../composed/command-palette'\nimport { useMotion } from '../motion/motion-provider'\nimport {\n Dialog,\n DialogContentRaw,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n} from '../ui/dialog'\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport { getIsMac, getModifierDisplay,matchesKeybinding } from '../ui/lib/keybinding'\nimport { springs,tweens } from '../ui/lib/motion'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport { VisuallyHidden } from '../ui/visually-hidden'\n\n// -----------------------------------------------------------------------\n// GradientBorderWrap — animated gradient border during processing\n// -----------------------------------------------------------------------\n\n/**\n * Wraps the input row with an animated gradient border during processing.\n * Uses the Devalok brand palette (pink → purple → magenta) flowing around\n * the border. When inactive, renders children directly with no wrapper overhead.\n *\n * Technique: outer div with gradient background + padding-[1.5px] creates\n * a visible gradient border. The inner content covers the center, leaving\n * only the edge visible as a \"border\".\n */\nfunction GradientBorderWrap({\n active,\n rounded,\n reducedMotion,\n children,\n}: {\n active: boolean\n rounded: string\n reducedMotion: boolean\n children: React.ReactNode\n}) {\n if (!active) return <>{children}</>\n\n if (reducedMotion) {\n return (\n <div className={cn('p-[1.5px] bg-accent-9', rounded)}>\n {children}\n </div>\n )\n }\n\n return (\n <motion.div\n className={cn('relative p-[1.5px]', rounded)}\n style={{\n background: 'linear-gradient(var(--gradient-angle, 0deg), #D33163, #9B5DE5, #C850C0, #D33163)',\n backgroundSize: '300% 300%',\n }}\n animate={{\n // Rotate the gradient angle — creates the flowing border effect\n // Using CSS custom property animation via backgroundPosition as proxy\n backgroundPosition: ['0% 0%', '100% 100%', '0% 0%'],\n }}\n transition={{\n backgroundPosition: {\n duration: 4,\n repeat: Infinity,\n ease: 'linear',\n },\n }}\n >\n {children}\n </motion.div>\n )\n}\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\n/**\n * Unified AI command interface with three visual variants:\n * - `hero`: full-featured inline bar with greeting, animated placeholder rotation, and hints\n * - `inline`: compact bar for embedding in panels or toolbars\n * - `floating`: modal overlay with global keybinding (same pattern as CommandPalette)\n *\n * Supports both command-palette filtering (when `groups` provided) and\n * natural-language AI submission via `onSubmit`.\n */\nexport interface CommandBarProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'onSubmit'> {\n // -- AI submission --\n /** Called when the user submits a query (Enter key). */\n onSubmit?: (query: string) => void\n /** Current interaction state. Controls visual feedback (gradient border, placeholder). */\n state?: 'idle' | 'typing' | 'processing' | 'responded'\n\n // -- Command palette mode (optional) --\n /** When provided, enables command-palette filtering alongside AI submission. */\n groups?: CommandGroup[]\n onSearch?: (query: string) => void\n emptyMessage?: string\n emptyState?: React.ReactNode\n\n // -- Visual --\n /** Layout variant. @default 'hero' */\n variant?: 'hero' | 'inline' | 'floating'\n /** Placeholder text, or an array of strings that rotate on an interval. */\n placeholder?: string | string[]\n /** Rotation interval in ms when `placeholder` is an array. @default 4000 */\n placeholderInterval?: number\n /** Greeting text shown above the input in `hero` variant. */\n greeting?: string\n /** Hint strings shown below the input in `hero` variant. */\n hints?: string[]\n agentName?: string\n agentIcon?: React.ReactNode\n\n // -- Floating variant (modal) --\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n /** Keybinding to toggle the floating bar. @default 'mod+k' */\n keybinding?: string | string[] | false\n\n // -- Interaction --\n disabled?: boolean\n maxHeight?: string | number\n\n // -- Composition --\n children?: React.ReactNode\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\nfunction getFilterValue(item: CommandItem): string {\n if (item.filterValue) return item.filterValue\n if (typeof item.label === 'string') return item.label\n return ''\n}\n\nfunction getFilterDescription(item: CommandItem): string {\n if (typeof item.description === 'string') return item.description\n return ''\n}\n\n// -----------------------------------------------------------------------\n// Rotating Placeholder\n// -----------------------------------------------------------------------\n\nfunction RotatingPlaceholder({\n placeholders,\n interval,\n paused,\n}: {\n placeholders: string[]\n interval: number\n paused: boolean\n}) {\n const [currentIndex, setCurrentIndex] = React.useState(0)\n const { reducedMotion } = useMotion()\n\n React.useEffect(() => {\n if (paused || placeholders.length <= 1) return\n const timer = setInterval(() => {\n setCurrentIndex((prev) => (prev + 1) % placeholders.length)\n }, interval)\n return () => clearInterval(timer)\n }, [paused, placeholders.length, interval])\n\n if (reducedMotion) {\n return (\n <span className=\"pointer-events-none absolute text-surface-fg-subtle\">\n {placeholders[currentIndex]}\n </span>\n )\n }\n\n return (\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={placeholders[currentIndex]}\n initial={{ opacity: 0, y: -4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 4 }}\n transition={tweens.fade}\n className=\"pointer-events-none absolute text-surface-fg-subtle\"\n >\n {placeholders[currentIndex]}\n </motion.span>\n </AnimatePresence>\n )\n}\n\n// -----------------------------------------------------------------------\n// CommandBar\n// -----------------------------------------------------------------------\n\nconst CommandBar = React.forwardRef<HTMLDivElement, CommandBarProps>(\n function CommandBar(\n {\n onSubmit,\n state = 'idle',\n groups = [],\n onSearch,\n emptyMessage = 'No results found.',\n emptyState,\n variant = 'hero',\n placeholder = 'Ask anything...',\n placeholderInterval = 5000,\n greeting,\n hints,\n agentName,\n agentIcon,\n open: openProp,\n defaultOpen,\n onOpenChange,\n keybinding = 'mod+j',\n disabled = false,\n maxHeight = '320px',\n children,\n className,\n ...props\n },\n ref,\n ) {\n // -- Controlled/uncontrolled open state (floating) --\n const isControlled = openProp !== undefined\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const open = isControlled ? openProp : internalOpen\n\n const openRef = React.useRef(open)\n openRef.current = open\n\n const setOpen = React.useCallback(\n (nextOpen: boolean | ((prev: boolean) => boolean)) => {\n const resolved =\n typeof nextOpen === 'function' ? nextOpen(openRef.current) : nextOpen\n if (!isControlled) {\n setInternalOpen(resolved)\n }\n onOpenChange?.(resolved)\n },\n [isControlled, onOpenChange],\n )\n\n // -- Core state --\n const [query, setQuery] = React.useState('')\n const [activeIndex, setActiveIndex] = React.useState(-1)\n const [lastQuery, setLastQuery] = React.useState('')\n const [isFocused, setIsFocused] = React.useState(false)\n const [shake, setShake] = React.useState(false)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n const instanceId = React.useId()\n const listboxId = `command-bar-listbox-${instanceId}`\n\n // -- Motion --\n const { reducedMotion: isReduced } = useMotion()\n const noMotionTransition = { duration: 0 }\n\n // -- Platform detection --\n const isMac = React.useMemo(() => getIsMac(), [])\n\n // -- Placeholders --\n const placeholders = React.useMemo(\n () => (Array.isArray(placeholder) ? placeholder : [placeholder]),\n [placeholder],\n )\n\n // -- Has groups --\n const hasGroups = groups.length > 0\n\n // -- Filter groups --\n const filteredGroups = React.useMemo(() => {\n if (!hasGroups) return []\n if (!query.trim()) return groups\n const q = query.toLowerCase()\n return groups\n .map((group) => ({\n ...group,\n items: group.items.filter(\n (item) =>\n getFilterValue(item).toLowerCase().includes(q) ||\n getFilterDescription(item).toLowerCase().includes(q),\n ),\n }))\n .filter((group) => group.items.length > 0)\n }, [groups, query, hasGroups])\n\n const filteredItems = React.useMemo(\n () => filteredGroups.flatMap((g) => g.items),\n [filteredGroups],\n )\n\n // Build item index map for keyboard navigation\n const itemIndexMap = React.useMemo(() => {\n const map = new Map<string, number>()\n let idx = 0\n for (const group of filteredGroups) {\n for (const item of group.items) {\n map.set(item.id, idx++)\n }\n }\n return map\n }, [filteredGroups])\n\n // -- Max height CSS --\n const maxHeightValue =\n typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight\n\n // -- Global keybinding (floating variant) --\n React.useEffect(() => {\n if (variant !== 'floating' || keybinding === false) return\n\n const bindings = Array.isArray(keybinding) ? keybinding : [keybinding]\n\n function handleKeyDown(e: KeyboardEvent) {\n for (const binding of bindings) {\n if (matchesKeybinding(e, binding)) {\n e.preventDefault()\n setOpen((prev) => !prev)\n return\n }\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [variant, keybinding, setOpen])\n\n // -- Reset on floating open --\n React.useEffect(() => {\n if (variant === 'floating' && open) {\n setQuery('')\n setActiveIndex(-1)\n requestAnimationFrame(() => {\n inputRef.current?.focus()\n })\n }\n }, [variant, open])\n\n // -- Scroll active item into view --\n React.useEffect(() => {\n if (activeIndex < 0) return\n const activeEl = listRef.current?.querySelector(\n `[data-command-index=\"${activeIndex}\"]`,\n )\n activeEl?.scrollIntoView({ block: 'nearest' })\n }, [activeIndex])\n\n // -- Query change handler --\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setActiveIndex(hasGroups && value.trim() ? 0 : -1)\n onSearch?.(value)\n }\n\n // -- Submit handler --\n const handleSubmit = React.useCallback(() => {\n if (!query.trim() || disabled) return\n setLastQuery(query)\n onSubmit?.(query)\n }, [query, disabled, onSubmit])\n\n // -- Keyboard handler --\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown': {\n if (!hasGroups || filteredItems.length === 0) return\n e.preventDefault()\n setActiveIndex((prev) =>\n prev < filteredItems.length - 1 ? prev + 1 : 0,\n )\n break\n }\n case 'ArrowUp': {\n if (hasGroups && filteredItems.length > 0) {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev > 0 ? prev - 1 : filteredItems.length - 1,\n )\n } else if (!hasGroups && !query && lastQuery) {\n // Recall last query\n e.preventDefault()\n setQuery(lastQuery)\n }\n break\n }\n case 'Enter': {\n e.preventDefault()\n const isCmdEnter = e.metaKey || e.ctrlKey\n\n if (isCmdEnter) {\n // Cmd+Enter always submits\n handleSubmit()\n } else if (\n hasGroups &&\n activeIndex >= 0 &&\n filteredItems[activeIndex]\n ) {\n // Enter selects active command item\n filteredItems[activeIndex].onSelect()\n if (variant === 'floating') setOpen(false)\n } else {\n // Enter submits query\n handleSubmit()\n }\n break\n }\n case 'Escape': {\n e.preventDefault()\n if (state === 'responded') {\n setQuery('')\n } else if (variant === 'floating') {\n setOpen(false)\n } else {\n inputRef.current?.blur()\n }\n break\n }\n }\n }\n\n // -- Clear handler --\n const handleClear = () => {\n setQuery('')\n setActiveIndex(-1)\n inputRef.current?.focus()\n }\n\n // -- Shake animation reset --\n React.useEffect(() => {\n if (shake) {\n const timer = setTimeout(() => setShake(false), 500)\n return () => clearTimeout(timer)\n }\n }, [shake])\n\n // -- Shared spring/tween for reduced motion --\n const springSnappy = isReduced ? noMotionTransition : springs.snappy\n const tweenFade = isReduced ? noMotionTransition : tweens.fade\n const noInit = isReduced ? { opacity: 1, scale: 1, y: 0 } : undefined\n\n // =====================================================================\n // Shared Input Row\n // =====================================================================\n const isCompact = variant === 'inline'\n const isProcessing = state === 'processing'\n const isResponded = state === 'responded'\n\n const renderInputRow = () => (\n <GradientBorderWrap\n active={isProcessing}\n rounded={isCompact ? 'rounded-control' : 'rounded-surface'}\n reducedMotion={isReduced}\n >\n <div\n className={cn(\n 'flex items-center gap-ds-04 border bg-surface-overlay transition-colors transition-shadow duration-fast-02 ease-productive-standard',\n isCompact\n ? 'rounded-control px-ds-04'\n : 'rounded-surface px-ds-05',\n isProcessing\n ? 'border-transparent'\n : 'border-surface-border-strong',\n isFocused && !isProcessing && 'border-accent-7 shadow-ring',\n shake && 'animate-shake',\n )}\n >\n {/* Search icon */}\n <Icon\n icon={IconSearch}\n size={isCompact ? 'xs' : 'sm'}\n stroke=\"light\"\n className={cn(\n 'shrink-0 transition-colors duration-fast-02 ease-productive-standard',\n isFocused ? 'text-accent-9' : 'text-surface-fg-subtle',\n )}\n />\n\n {/* Input wrapper */}\n <div className=\"relative flex flex-1 items-center\">\n {!query && !isFocused && placeholders.length > 1 && (\n <RotatingPlaceholder\n placeholders={placeholders}\n interval={placeholderInterval}\n paused={isFocused || !!query}\n />\n )}\n <input\n ref={inputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n placeholder={\n placeholders.length === 1 || isFocused ? placeholders[0] : ''\n }\n readOnly={isProcessing}\n disabled={disabled}\n role=\"combobox\"\n aria-expanded={hasGroups && filteredItems.length > 0}\n aria-controls={hasGroups ? listboxId : undefined}\n aria-activedescendant={\n hasGroups && activeIndex >= 0 && filteredItems[activeIndex]\n ? `command-bar-item-${instanceId}-${filteredItems[activeIndex].id}`\n : undefined\n }\n aria-autocomplete={hasGroups ? 'list' : undefined}\n aria-label={agentName ? `Ask ${agentName}` : 'AI Command Bar'}\n className={cn(\n 'flex-1 bg-transparent text-surface-fg outline-hidden',\n 'placeholder:text-surface-fg-subtle',\n isCompact ? 'h-9 text-body-sm' : 'h-12 text-body-lg',\n isProcessing && 'cursor-wait',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n />\n </div>\n\n {/* Right side: spinner / clear / shortcut badge */}\n {isProcessing ? (\n <span data-testid=\"command-bar-spinner\" className=\"shrink-0\">\n <Icon\n icon={IconLoader2}\n size={isCompact ? 'xs' : 'sm'}\n stroke=\"light\"\n animate=\"spin\"\n className=\"text-accent-9\"\n />\n </span>\n ) : isResponded ? (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"shrink-0 rounded-control-inner p-ds-01 text-surface-fg-subtle transition-colors duration-fast-01 hover:bg-surface-raised-hover hover:text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9\"\n aria-label=\"Clear\"\n title=\"Clear\"\n >\n <Icon\n icon={IconX}\n size={isCompact ? 'xs' : 'sm'}\n stroke=\"light\"\n />\n </button>\n ) : variant === 'hero' ? (\n <AnimatePresence>\n {!isFocused && (\n <motion.kbd\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={isReduced ? undefined : { opacity: 0 }}\n transition={tweenFade}\n className=\"hidden shrink-0 select-none rounded-control border border-card-strong bg-surface-raised px-ds-02b py-ds-01 text-body-sm font-medium text-surface-fg-subtle shadow-kbd sm:inline-flex\"\n >\n {getModifierDisplay(isMac)}J\n </motion.kbd>\n )}\n </AnimatePresence>\n ) : null}\n </div>\n </GradientBorderWrap>\n )\n\n // =====================================================================\n // Command Results (shared between variants)\n // =====================================================================\n const renderCommandResults = () => {\n if (!hasGroups) return null\n\n const showResults =\n filteredItems.length > 0 || (query.trim() && filteredGroups.length === 0)\n\n if (!showResults && !query.trim()) return null\n\n return (\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Command results\"\n className=\"overflow-y-auto px-ds-03 py-ds-03\"\n style={{ maxHeight: maxHeightValue }}\n >\n {filteredGroups.length === 0 && query.trim() && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center justify-center py-ds-07\"\n >\n {emptyState ?? (\n <p className=\"text-body-md text-surface-fg-subtle\">\n {emptyMessage}\n </p>\n )}\n </motion.div>\n )}\n\n {filteredGroups.map((group, groupIdx) => (\n <motion.div\n key={group.label}\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={\n isReduced\n ? noMotionTransition\n : { ...tweens.fade, delay: groupIdx * 0.06 }\n }\n className=\"mb-ds-02\"\n >\n <div className=\"px-ds-03 pb-ds-02 pt-ds-03\">\n <span className=\"text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\">\n {group.label}\n </span>\n </div>\n\n {group.items.map((item) => {\n const itemIndex = itemIndexMap.get(item.id) ?? 0\n const isActive = itemIndex === activeIndex\n return (\n <motion.button\n key={item.id}\n id={`command-bar-item-${instanceId}-${item.id}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-command-index={itemIndex}\n initial={noInit ?? { opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={\n isReduced\n ? noMotionTransition\n : { ...springs.snappy, delay: itemIndex * 0.03 }\n }\n onClick={() => {\n item.onSelect()\n if (variant === 'floating') setOpen(false)\n }}\n onMouseEnter={() => setActiveIndex(itemIndex)}\n className={cn(\n 'flex w-full items-center gap-ds-04 rounded-surface px-ds-03 py-ds-03 text-left transition-[color,background-color] duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-surface-raised-hover text-surface-fg'\n : 'text-surface-fg-muted hover:bg-surface-raised',\n )}\n >\n {item.icon && (\n <span\n className={cn(\n '[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0 transition-colors duration-fast-02 ease-productive-standard',\n isActive\n ? 'text-accent-11'\n : 'text-surface-fg-subtle',\n )}\n aria-hidden=\"true\"\n >\n <IconProvider size=\"sm\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n )}\n <div className=\"flex flex-1 flex-col\">\n <span className=\"text-body-md\">\n {item.renderLabel\n ? item.renderLabel(query)\n : item.label}\n </span>\n {item.description && (\n <span className=\"text-body-sm text-surface-fg-subtle\">\n {item.description}\n </span>\n )}\n </div>\n <AnimatePresence>\n {isActive && (\n <motion.span\n initial={isReduced ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={isReduced ? undefined : { opacity: 0 }}\n transition={tweenFade}\n className=\"inline-flex shrink-0\"\n >\n <Icon\n icon={IconCornerDownLeft}\n size=\"sm\"\n stroke=\"light\"\n className=\"text-surface-fg-subtle\"\n />\n </motion.span>\n )}\n </AnimatePresence>\n </motion.button>\n )\n })}\n </motion.div>\n ))}\n </div>\n )\n }\n\n // =====================================================================\n // Hero Variant\n // =====================================================================\n if (variant === 'hero') {\n return (\n <div\n ref={ref}\n role=\"search\"\n className={cn(\n 'bg-surface-raised rounded-overlay-lg shadow-raised p-ds-07',\n className,\n )}\n {...props}\n >\n {greeting && (\n <p className=\"text-heading-xs text-surface-fg-muted mb-ds-04\">\n {greeting}\n </p>\n )}\n\n {renderInputRow()}\n {renderCommandResults()}\n\n {/* Hints */}\n {hints && hints.length > 0 && (\n <div className=\"mt-ds-04 flex flex-wrap gap-ds-02b\">\n {hints.map((hint) => (\n <button\n key={hint}\n type=\"button\"\n onClick={() => {\n setQuery(hint)\n onSearch?.(hint)\n inputRef.current?.focus()\n }}\n className=\"rounded-control border border-card-strong bg-surface-overlay px-ds-03 py-ds-01 text-body-sm text-surface-fg-subtle transition-colors duration-fast-02 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted\"\n >\n {hint}\n </button>\n ))}\n </div>\n )}\n\n {/* Response area (children) */}\n {children && <div className=\"mt-ds-05\">{children}</div>}\n </div>\n )\n }\n\n // =====================================================================\n // Inline Variant\n // =====================================================================\n if (variant === 'inline') {\n return (\n <div\n ref={ref}\n role=\"search\"\n className={cn('w-full', className)}\n {...props}\n >\n {renderInputRow()}\n {renderCommandResults()}\n {children && <div className=\"mt-ds-03\">{children}</div>}\n </div>\n )\n }\n\n // =====================================================================\n // Floating Variant\n // =====================================================================\n const handleDialogOpenChange = (nextOpen: boolean) => {\n setOpen(nextOpen)\n }\n\n return (\n <Dialog open={open} onOpenChange={handleDialogOpenChange}>\n <DialogPortal>\n <DialogOverlay className=\"fixed inset-0 z-overlay bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\" />\n <DialogContentRaw\n ref={ref}\n {...props}\n className={cn(\n 'fixed left-1/2 top-[20%] z-modal w-full max-w-[560px] -translate-x-1/2',\n 'overflow-hidden rounded-overlay-lg bg-surface-overlay shadow-overlay',\n 'duration-moderate-02 data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[state=closed]:slide-out-to-left-1/2 data-[state=open]:slide-in-from-left-1/2',\n 'data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2',\n className,\n )}\n >\n <VisuallyHidden>\n <DialogTitle>AI Command Bar</DialogTitle>\n <DialogDescription>\n Search commands or ask a question\n </DialogDescription>\n </VisuallyHidden>\n\n <div className=\"p-ds-04\">{renderInputRow()}</div>\n\n {renderCommandResults()}\n\n {children && (\n <div className=\"border-t border-surface-border-strong p-ds-04\">\n {children}\n </div>\n )}\n\n {/* Footer hints */}\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center gap-ds-05 border-t border-surface-border-strong px-ds-05 py-ds-03\"\n >\n {hasGroups && (\n <div className=\"flex items-center gap-ds-02b\">\n <div className=\"flex items-center gap-ds-01\">\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowUp} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowDown} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n </div>\n <span className=\"text-caption text-surface-fg-subtle\">\n Navigate\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-ds-02b\">\n <kbd className=\"inline-flex h-[20px] items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b shadow-kbd\">\n <Icon icon={IconCornerDownLeft} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n <span className=\"text-caption text-surface-fg-subtle\">\n Submit\n </span>\n </div>\n <div className=\"flex items-center gap-ds-02b\">\n <kbd className=\"inline-flex h-[20px] items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b text-caption font-medium text-surface-fg-subtle shadow-kbd\">\n Esc\n </kbd>\n <span className=\"text-caption text-surface-fg-subtle\">\n Close\n </span>\n </div>\n </motion.div>\n </DialogContentRaw>\n </DialogPortal>\n </Dialog>\n )\n },\n)\n\nCommandBar.displayName = 'CommandBar'\n\nexport { CommandBar }\nexport type { CommandGroup, CommandItem }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"command-bar.js","names":[],"sources":["../../src/ai/command-bar.tsx"],"sourcesContent":["'use client'\n\n/**\n * CommandBar -- Unified AI command interface.\n *\n * Three variants:\n * - hero: Full-featured inline bar with greeting, hints, placeholder rotation\n * - inline: Compact inline bar for embedding in panels/toolbars\n * - floating: Modal overlay (same pattern as CommandPalette) with global keybinding\n *\n * Supports both command-palette filtering (when `groups` provided) and\n * AI natural-language submission via `onSubmit`.\n */\nimport {\n IconArrowDown,\n IconArrowUp,\n IconCornerDownLeft,\n IconLoader2,\n IconSearch,\n IconX,\n} from '@tabler/icons-react'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport type { CommandGroup, CommandItem } from '../composed/command-palette'\nimport { useMotion } from '../motion/motion-provider'\nimport {\n Dialog,\n DialogContentRaw,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n} from '../ui/dialog'\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport { getIsMac, getModifierDisplay,matchesKeybinding } from '../ui/lib/keybinding'\nimport { springs,tweens } from '../ui/lib/motion'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport { VisuallyHidden } from '../ui/visually-hidden'\n\n// -----------------------------------------------------------------------\n// GradientBorderWrap — animated gradient border during processing\n// -----------------------------------------------------------------------\n\n/**\n * Wraps the input row with an animated gradient border during processing.\n * Uses the Devalok brand palette (pink → purple → magenta) flowing around\n * the border. When inactive, renders children directly with no wrapper overhead.\n *\n * Technique: outer div with gradient background + padding-[1.5px] creates\n * a visible gradient border. The inner content covers the center, leaving\n * only the edge visible as a \"border\".\n */\nfunction GradientBorderWrap({\n active,\n rounded,\n reducedMotion,\n children,\n}: {\n active: boolean\n rounded: string\n reducedMotion: boolean\n children: React.ReactNode\n}) {\n if (!active) return <>{children}</>\n\n if (reducedMotion) {\n return (\n <div className={cn('p-[1.5px] bg-accent-9', rounded)}>\n {children}\n </div>\n )\n }\n\n return (\n <motion.div\n className={cn('relative p-[1.5px]', rounded)}\n style={{\n background: 'linear-gradient(var(--gradient-angle, 0deg), #D33163, #9B5DE5, #C850C0, #D33163)',\n backgroundSize: '300% 300%',\n }}\n animate={{\n // Rotate the gradient angle — creates the flowing border effect\n // Using CSS custom property animation via backgroundPosition as proxy\n backgroundPosition: ['0% 0%', '100% 100%', '0% 0%'],\n }}\n transition={{\n backgroundPosition: {\n duration: 4,\n repeat: Infinity,\n ease: 'linear',\n },\n }}\n >\n {children}\n </motion.div>\n )\n}\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\n/**\n * Unified AI command interface with three visual variants:\n * - `hero`: full-featured inline bar with greeting, animated placeholder rotation, and hints\n * - `inline`: compact bar for embedding in panels or toolbars\n * - `floating`: modal overlay with global keybinding (same pattern as CommandPalette)\n *\n * Supports both command-palette filtering (when `groups` provided) and\n * natural-language AI submission via `onSubmit`.\n */\nexport interface CommandBarProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'onSubmit'> {\n // -- AI submission --\n /** Called when the user submits a query (Enter key). */\n onSubmit?: (query: string) => void\n /** Current interaction state. Controls visual feedback (gradient border, placeholder). */\n state?: 'idle' | 'typing' | 'processing' | 'responded'\n\n // -- Command palette mode (optional) --\n /** When provided, enables command-palette filtering alongside AI submission. */\n groups?: CommandGroup[]\n onSearch?: (query: string) => void\n emptyMessage?: string\n emptyState?: React.ReactNode\n\n // -- Visual --\n /** Layout variant. @default 'hero' */\n variant?: 'hero' | 'inline' | 'floating'\n /** Placeholder text, or an array of strings that rotate on an interval. */\n placeholder?: string | string[]\n /** Rotation interval in ms when `placeholder` is an array. @default 4000 */\n placeholderInterval?: number\n /** Greeting text shown above the input in `hero` variant. */\n greeting?: string\n /** Hint strings shown below the input in `hero` variant. */\n hints?: string[]\n agentName?: string\n agentIcon?: React.ReactNode\n\n // -- Floating variant (modal) --\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n /** Keybinding to toggle the floating bar. @default 'mod+k' */\n keybinding?: string | string[] | false\n\n // -- Interaction --\n disabled?: boolean\n maxHeight?: string | number\n\n // -- Composition --\n children?: React.ReactNode\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\nfunction getFilterValue(item: CommandItem): string {\n if (item.filterValue) return item.filterValue\n if (typeof item.label === 'string') return item.label\n return ''\n}\n\nfunction getFilterDescription(item: CommandItem): string {\n if (typeof item.description === 'string') return item.description\n return ''\n}\n\n// -----------------------------------------------------------------------\n// Rotating Placeholder\n// -----------------------------------------------------------------------\n\nfunction RotatingPlaceholder({\n placeholders,\n interval,\n paused,\n}: {\n placeholders: string[]\n interval: number\n paused: boolean\n}) {\n const [currentIndex, setCurrentIndex] = React.useState(0)\n const { reducedMotion } = useMotion()\n\n React.useEffect(() => {\n if (paused || placeholders.length <= 1) return\n const timer = setInterval(() => {\n setCurrentIndex((prev) => (prev + 1) % placeholders.length)\n }, interval)\n return () => clearInterval(timer)\n }, [paused, placeholders.length, interval])\n\n if (reducedMotion) {\n return (\n <span className=\"pointer-events-none absolute text-surface-fg-subtle\">\n {placeholders[currentIndex]}\n </span>\n )\n }\n\n return (\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={placeholders[currentIndex]}\n initial={{ opacity: 0, y: -4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 4 }}\n transition={tweens.fade}\n className=\"pointer-events-none absolute text-surface-fg-subtle\"\n >\n {placeholders[currentIndex]}\n </motion.span>\n </AnimatePresence>\n )\n}\n\n// -----------------------------------------------------------------------\n// CommandBar\n// -----------------------------------------------------------------------\n\nconst CommandBar = React.forwardRef<HTMLDivElement, CommandBarProps>(\n function CommandBar(\n {\n onSubmit,\n state = 'idle',\n groups = [],\n onSearch,\n emptyMessage = 'No results found.',\n emptyState,\n variant = 'hero',\n placeholder = 'Ask anything...',\n placeholderInterval = 5000,\n greeting,\n hints,\n agentName,\n agentIcon,\n open: openProp,\n defaultOpen,\n onOpenChange,\n keybinding = 'mod+j',\n disabled = false,\n maxHeight = '320px',\n children,\n className,\n ...props\n },\n ref,\n ) {\n // -- Controlled/uncontrolled open state (floating) --\n const isControlled = openProp !== undefined\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const open = isControlled ? openProp : internalOpen\n\n const openRef = React.useRef(open)\n openRef.current = open\n\n const setOpen = React.useCallback(\n (nextOpen: boolean | ((prev: boolean) => boolean)) => {\n const resolved =\n typeof nextOpen === 'function' ? nextOpen(openRef.current) : nextOpen\n if (!isControlled) {\n setInternalOpen(resolved)\n }\n onOpenChange?.(resolved)\n },\n [isControlled, onOpenChange],\n )\n\n // -- Core state --\n const [query, setQuery] = React.useState('')\n const [activeIndex, setActiveIndex] = React.useState(-1)\n const [lastQuery, setLastQuery] = React.useState('')\n const [isFocused, setIsFocused] = React.useState(false)\n const [shake, setShake] = React.useState(false)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n const instanceId = React.useId()\n const listboxId = `command-bar-listbox-${instanceId}`\n\n // -- Motion --\n const { reducedMotion: isReduced } = useMotion()\n const noMotionTransition = { duration: 0 }\n\n // -- Platform detection --\n const isMac = React.useMemo(() => getIsMac(), [])\n\n // -- Placeholders --\n const placeholders = React.useMemo(\n () => (Array.isArray(placeholder) ? placeholder : [placeholder]),\n [placeholder],\n )\n\n // -- Has groups --\n const hasGroups = groups.length > 0\n\n // -- Filter groups --\n const filteredGroups = React.useMemo(() => {\n if (!hasGroups) return []\n if (!query.trim()) return groups\n const q = query.toLowerCase()\n return groups\n .map((group) => ({\n ...group,\n items: group.items.filter(\n (item) =>\n getFilterValue(item).toLowerCase().includes(q) ||\n getFilterDescription(item).toLowerCase().includes(q),\n ),\n }))\n .filter((group) => group.items.length > 0)\n }, [groups, query, hasGroups])\n\n const filteredItems = React.useMemo(\n () => filteredGroups.flatMap((g) => g.items),\n [filteredGroups],\n )\n\n // Build item index map for keyboard navigation\n const itemIndexMap = React.useMemo(() => {\n const map = new Map<string, number>()\n let idx = 0\n for (const group of filteredGroups) {\n for (const item of group.items) {\n map.set(item.id, idx++)\n }\n }\n return map\n }, [filteredGroups])\n\n // -- Max height CSS --\n const maxHeightValue =\n typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight\n\n // -- Global keybinding (floating variant) --\n React.useEffect(() => {\n if (variant !== 'floating' || keybinding === false) return\n\n const bindings = Array.isArray(keybinding) ? keybinding : [keybinding]\n\n function handleKeyDown(e: KeyboardEvent) {\n for (const binding of bindings) {\n if (matchesKeybinding(e, binding)) {\n e.preventDefault()\n setOpen((prev) => !prev)\n return\n }\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [variant, keybinding, setOpen])\n\n // -- Reset on floating open --\n React.useEffect(() => {\n if (variant === 'floating' && open) {\n setQuery('')\n setActiveIndex(-1)\n requestAnimationFrame(() => {\n inputRef.current?.focus()\n })\n }\n }, [variant, open])\n\n // -- Scroll active item into view --\n React.useEffect(() => {\n if (activeIndex < 0) return\n const activeEl = listRef.current?.querySelector(\n `[data-command-index=\"${activeIndex}\"]`,\n )\n activeEl?.scrollIntoView({ block: 'nearest' })\n }, [activeIndex])\n\n // -- Query change handler --\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setActiveIndex(hasGroups && value.trim() ? 0 : -1)\n onSearch?.(value)\n }\n\n // -- Submit handler --\n const handleSubmit = React.useCallback(() => {\n if (!query.trim() || disabled) return\n setLastQuery(query)\n onSubmit?.(query)\n }, [query, disabled, onSubmit])\n\n // -- Keyboard handler --\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown': {\n if (!hasGroups || filteredItems.length === 0) return\n e.preventDefault()\n setActiveIndex((prev) =>\n prev < filteredItems.length - 1 ? prev + 1 : 0,\n )\n break\n }\n case 'ArrowUp': {\n if (hasGroups && filteredItems.length > 0) {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev > 0 ? prev - 1 : filteredItems.length - 1,\n )\n } else if (!hasGroups && !query && lastQuery) {\n // Recall last query\n e.preventDefault()\n setQuery(lastQuery)\n }\n break\n }\n case 'Enter': {\n e.preventDefault()\n const isCmdEnter = e.metaKey || e.ctrlKey\n\n if (isCmdEnter) {\n // Cmd+Enter always submits\n handleSubmit()\n } else if (\n hasGroups &&\n activeIndex >= 0 &&\n filteredItems[activeIndex]\n ) {\n // Enter selects active command item\n filteredItems[activeIndex].onSelect()\n if (variant === 'floating') setOpen(false)\n } else {\n // Enter submits query\n handleSubmit()\n }\n break\n }\n case 'Escape': {\n e.preventDefault()\n if (state === 'responded') {\n setQuery('')\n } else if (variant === 'floating') {\n setOpen(false)\n } else {\n inputRef.current?.blur()\n }\n break\n }\n }\n }\n\n // -- Clear handler --\n const handleClear = () => {\n setQuery('')\n setActiveIndex(-1)\n inputRef.current?.focus()\n }\n\n // -- Shake animation reset --\n React.useEffect(() => {\n if (shake) {\n const timer = setTimeout(() => setShake(false), 500)\n return () => clearTimeout(timer)\n }\n }, [shake])\n\n // -- Shared spring/tween for reduced motion --\n const springSnappy = isReduced ? noMotionTransition : springs.snappy\n const tweenFade = isReduced ? noMotionTransition : tweens.fade\n const noInit = isReduced ? { opacity: 1, scale: 1, y: 0 } : undefined\n\n // =====================================================================\n // Shared Input Row\n // =====================================================================\n const isCompact = variant === 'inline'\n const isProcessing = state === 'processing'\n const isResponded = state === 'responded'\n\n const renderInputRow = () => (\n <GradientBorderWrap\n active={isProcessing}\n rounded={isCompact ? 'rounded-control' : 'rounded-surface'}\n reducedMotion={isReduced}\n >\n <div\n className={cn(\n 'flex items-center gap-ds-04 border bg-surface-overlay transition-colors transition-shadow duration-fast-02 ease-productive-standard',\n isCompact\n ? 'rounded-control px-ds-04'\n : 'rounded-surface px-ds-05',\n isProcessing\n ? 'border-transparent'\n : 'border-surface-border-strong',\n isFocused && !isProcessing && 'border-accent-7 shadow-ring',\n shake && 'animate-shake',\n )}\n >\n {/* Search icon */}\n <Icon\n icon={IconSearch}\n size={isCompact ? 'xs' : 'sm'}\n stroke=\"light\"\n className={cn(\n 'shrink-0 transition-colors duration-fast-02 ease-productive-standard',\n isFocused ? 'text-accent-9' : 'text-surface-fg-subtle',\n )}\n />\n\n {/* Input wrapper */}\n <div className=\"relative flex flex-1 items-center\">\n {!query && !isFocused && placeholders.length > 1 && (\n <RotatingPlaceholder\n placeholders={placeholders}\n interval={placeholderInterval}\n paused={isFocused || !!query}\n />\n )}\n <input\n ref={inputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n placeholder={\n placeholders.length === 1 || isFocused ? placeholders[0] : ''\n }\n readOnly={isProcessing}\n disabled={disabled}\n role=\"combobox\"\n aria-expanded={hasGroups && filteredItems.length > 0}\n aria-controls={hasGroups ? listboxId : undefined}\n aria-activedescendant={\n hasGroups && activeIndex >= 0 && filteredItems[activeIndex]\n ? `command-bar-item-${instanceId}-${filteredItems[activeIndex].id}`\n : undefined\n }\n aria-autocomplete={hasGroups ? 'list' : undefined}\n aria-label={agentName ? `Ask ${agentName}` : 'AI Command Bar'}\n className={cn(\n 'flex-1 bg-transparent text-surface-fg outline-hidden',\n 'placeholder:text-surface-fg-subtle',\n isCompact ? 'h-9 text-body-sm' : 'h-12 text-body-lg',\n isProcessing && 'cursor-wait',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n />\n </div>\n\n {/* Right side: spinner / clear / shortcut badge */}\n {isProcessing ? (\n <span data-testid=\"command-bar-spinner\" className=\"shrink-0\">\n <Icon\n icon={IconLoader2}\n size={isCompact ? 'xs' : 'sm'}\n stroke=\"light\"\n animate=\"spin\"\n className=\"text-accent-9\"\n />\n </span>\n ) : isResponded ? (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"shrink-0 rounded-control-inner p-ds-01 text-surface-fg-subtle transition-colors duration-fast-01 hover:bg-surface-raised-hover hover:text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9\"\n aria-label=\"Clear\"\n title=\"Clear\"\n >\n <Icon\n icon={IconX}\n size={isCompact ? 'xs' : 'sm'}\n stroke=\"light\"\n />\n </button>\n ) : variant === 'hero' ? (\n <AnimatePresence>\n {!isFocused && (\n <motion.kbd\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={isReduced ? undefined : { opacity: 0 }}\n transition={tweenFade}\n className=\"hidden shrink-0 select-none rounded-control border border-card-strong bg-surface-raised px-ds-02b py-ds-01 text-body-sm font-medium text-surface-fg-subtle shadow-kbd sm:inline-flex\"\n >\n {getModifierDisplay(isMac)}J\n </motion.kbd>\n )}\n </AnimatePresence>\n ) : null}\n </div>\n </GradientBorderWrap>\n )\n\n // =====================================================================\n // Command Results (shared between variants)\n // =====================================================================\n const renderCommandResults = () => {\n if (!hasGroups) return null\n\n const showResults =\n filteredItems.length > 0 || (query.trim() && filteredGroups.length === 0)\n\n if (!showResults && !query.trim()) return null\n\n return (\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Command results\"\n className=\"overflow-y-auto px-ds-03 py-ds-03\"\n style={{ maxHeight: maxHeightValue }}\n >\n {filteredGroups.length === 0 && query.trim() && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center justify-center py-ds-07\"\n >\n {emptyState ?? (\n <p className=\"text-body-md text-surface-fg-subtle\">\n {emptyMessage}\n </p>\n )}\n </motion.div>\n )}\n\n {filteredGroups.map((group, groupIdx) => (\n <motion.div\n key={group.label}\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={\n isReduced\n ? noMotionTransition\n : { ...tweens.fade, delay: groupIdx * 0.06 }\n }\n className=\"mb-ds-02\"\n >\n <div className=\"px-ds-03 pb-ds-02 pt-ds-03\">\n <span className=\"text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\">\n {group.label}\n </span>\n </div>\n\n {group.items.map((item) => {\n const itemIndex = itemIndexMap.get(item.id) ?? 0\n const isActive = itemIndex === activeIndex\n return (\n <motion.button\n key={item.id}\n id={`command-bar-item-${instanceId}-${item.id}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-command-index={itemIndex}\n initial={noInit ?? { opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={\n isReduced\n ? noMotionTransition\n : { ...springs.snappy, delay: itemIndex * 0.03 }\n }\n onClick={() => {\n item.onSelect()\n if (variant === 'floating') setOpen(false)\n }}\n onMouseEnter={() => setActiveIndex(itemIndex)}\n className={cn(\n 'flex w-full items-center gap-ds-04 rounded-surface px-ds-03 py-ds-03 text-left transition-[color,background-color] duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-surface-raised-hover text-surface-fg'\n : 'text-surface-fg-muted hover:bg-surface-raised',\n )}\n >\n {item.icon && (\n <span\n className={cn(\n '[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0 transition-colors duration-fast-02 ease-productive-standard',\n isActive\n ? 'text-accent-11'\n : 'text-surface-fg-subtle',\n )}\n aria-hidden=\"true\"\n >\n <IconProvider size=\"sm\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n )}\n <div className=\"flex flex-1 flex-col\">\n <span className=\"text-body-md\">\n {item.renderLabel\n ? item.renderLabel(query)\n : item.label}\n </span>\n {item.description && (\n <span className=\"text-body-sm text-surface-fg-subtle\">\n {item.description}\n </span>\n )}\n </div>\n <AnimatePresence>\n {isActive && (\n <motion.span\n initial={isReduced ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={isReduced ? undefined : { opacity: 0 }}\n transition={tweenFade}\n className=\"inline-flex shrink-0\"\n >\n <Icon\n icon={IconCornerDownLeft}\n size=\"sm\"\n stroke=\"light\"\n className=\"text-surface-fg-subtle\"\n />\n </motion.span>\n )}\n </AnimatePresence>\n </motion.button>\n )\n })}\n </motion.div>\n ))}\n </div>\n )\n }\n\n // =====================================================================\n // Hero Variant\n // =====================================================================\n if (variant === 'hero') {\n return (\n <div\n ref={ref}\n role=\"search\"\n className={cn(\n 'bg-surface-raised rounded-overlay-lg shadow-raised p-ds-07',\n className,\n )}\n {...props}\n >\n {greeting && (\n <p className=\"text-heading-xs text-surface-fg-muted mb-ds-04\">\n {greeting}\n </p>\n )}\n\n {renderInputRow()}\n {renderCommandResults()}\n\n {/* Hints */}\n {hints && hints.length > 0 && (\n <div className=\"mt-ds-04 flex flex-wrap gap-ds-02b\">\n {hints.map((hint) => (\n <button\n key={hint}\n type=\"button\"\n onClick={() => {\n setQuery(hint)\n onSearch?.(hint)\n inputRef.current?.focus()\n }}\n className=\"rounded-control border border-card-strong bg-surface-overlay px-ds-03 py-ds-01 text-body-sm text-surface-fg-subtle transition-colors duration-fast-02 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted\"\n >\n {hint}\n </button>\n ))}\n </div>\n )}\n\n {/* Response area (children) */}\n {children && <div className=\"mt-ds-05\">{children}</div>}\n </div>\n )\n }\n\n // =====================================================================\n // Inline Variant\n // =====================================================================\n if (variant === 'inline') {\n return (\n <div\n ref={ref}\n role=\"search\"\n className={cn('w-full', className)}\n {...props}\n >\n {renderInputRow()}\n {renderCommandResults()}\n {children && <div className=\"mt-ds-03\">{children}</div>}\n </div>\n )\n }\n\n // =====================================================================\n // Floating Variant\n // =====================================================================\n const handleDialogOpenChange = (nextOpen: boolean) => {\n setOpen(nextOpen)\n }\n\n return (\n <Dialog open={open} onOpenChange={handleDialogOpenChange}>\n <DialogPortal>\n <DialogOverlay className=\"fixed inset-0 z-overlay bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\" />\n <DialogContentRaw\n ref={ref}\n {...props}\n className={cn(\n 'fixed left-1/2 top-[20%] z-modal w-full max-w-[560px] -translate-x-1/2',\n 'overflow-hidden rounded-overlay-lg bg-surface-overlay shadow-overlay',\n 'duration-moderate-02 data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[state=closed]:slide-out-to-left-1/2 data-[state=open]:slide-in-from-left-1/2',\n 'data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2',\n className,\n )}\n >\n <VisuallyHidden>\n <DialogTitle>AI Command Bar</DialogTitle>\n <DialogDescription>\n Search commands or ask a question\n </DialogDescription>\n </VisuallyHidden>\n\n <div className=\"p-ds-04\">{renderInputRow()}</div>\n\n {renderCommandResults()}\n\n {children && (\n <div className=\"border-t border-surface-border-strong p-ds-04\">\n {children}\n </div>\n )}\n\n {/* Footer hints */}\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center gap-ds-05 border-t border-surface-border-strong px-ds-05 py-ds-03\"\n >\n {hasGroups && (\n <div className=\"flex items-center gap-ds-02b\">\n <div className=\"flex items-center gap-ds-01\">\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowUp} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowDown} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n </div>\n <span className=\"text-caption text-surface-fg-subtle\">\n Navigate\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-ds-02b\">\n <kbd className=\"inline-flex h-[20px] items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b shadow-kbd\">\n <Icon icon={IconCornerDownLeft} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n <span className=\"text-caption text-surface-fg-subtle\">\n Submit\n </span>\n </div>\n <div className=\"flex items-center gap-ds-02b\">\n <kbd className=\"inline-flex h-[20px] items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b text-caption font-medium text-surface-fg-subtle shadow-kbd\">\n Esc\n </kbd>\n <span className=\"text-caption text-surface-fg-subtle\">\n Close\n </span>\n </div>\n </motion.div>\n </DialogContentRaw>\n </DialogPortal>\n </Dialog>\n )\n },\n)\n\nCommandBar.displayName = 'CommandBar'\n\nexport { CommandBar }\nexport type { CommandGroup, CommandItem }\n"],"mappings":";;;;;;;;;;;;;;;AAuDA,SAAS,GAAmB,EAC1B,WACA,YACA,kBACA,eAMC;CAWD,OAVK,IAED,IAEA,kBAAC,OAAD;EAAK,WAAW,EAAG,yBAAyB,CAAO;EAChD;CACE,CAAA,IAKP,kBAAC,EAAO,KAAR;EACE,WAAW,EAAG,sBAAsB,CAAO;EAC3C,OAAO;GACL,YAAY;GACZ,gBAAgB;EAClB;EACA,SAAS,EAGP,oBAAoB;GAAC;GAAS;GAAa;EAAO,EACpD;EACA,YAAY,EACV,oBAAoB;GAClB,UAAU;GACV,QAAQ;GACR,MAAM;EACR,EACF;EAEC;CACS,CAAA,IA/BM,kBAAA,GAAA,EAAG,YAAW,CAAA;AAiCpC;AA+DA,SAAS,GAAe,GAA2B;CAGjD,OAFI,EAAK,cAAoB,EAAK,cAC9B,OAAO,EAAK,SAAU,WAAiB,EAAK,QACzC;AACT;AAEA,SAAS,GAAqB,GAA2B;CAEvD,OADI,OAAO,EAAK,eAAgB,WAAiB,EAAK,cAC/C;AACT;AAMA,SAAS,GAAoB,EAC3B,iBACA,aACA,aAKC;CACD,IAAM,CAAC,GAAc,KAAmB,EAAM,SAAS,CAAC,GAClD,EAAE,qBAAkB,EAAU;CAkBpC,OAhBA,EAAM,gBAAgB;EACpB,IAAI,KAAU,EAAa,UAAU,GAAG;EACxC,IAAM,IAAQ,kBAAkB;GAC9B,GAAiB,OAAU,IAAO,KAAK,EAAa,MAAM;EAC5D,GAAG,CAAQ;EACX,aAAa,cAAc,CAAK;CAClC,GAAG;EAAC;EAAQ,EAAa;EAAQ;CAAQ,CAAC,GAEtC,IAEA,kBAAC,QAAD;EAAM,WAAU;YACb,EAAa;CACV,CAAA,IAKR,kBAAC,GAAD;EAAiB,MAAK;YACpB,kBAAC,EAAO,MAAR;GAEE,SAAS;IAAE,SAAS;IAAG,GAAG;GAAG;GAC7B,SAAS;IAAE,SAAS;IAAG,GAAG;GAAE;GAC5B,MAAM;IAAE,SAAS;IAAG,GAAG;GAAE;GACzB,YAAY,EAAO;GACnB,WAAU;aAET,EAAa;EACH,GARN,EAAa,EAQP;CACE,CAAA;AAErB;AAMA,IAAM,IAAa,EAAM,WACvB,SACE,EACE,aACA,WAAQ,QACR,YAAS,CAAC,GACV,cACA,mBAAe,qBACf,gBACA,aAAU,QACV,iBAAc,mBACd,0BAAsB,KACtB,aACA,UACA,cACA,eACA,MAAM,GACN,iBACA,iBACA,gBAAa,SACb,cAAW,IACX,eAAY,SACZ,aACA,cACA,GAAG,KAEL,GACA;CAEA,IAAM,IAAe,MAAa,KAAA,GAC5B,CAAC,IAAc,MAAmB,EAAM,SAAS,MAAe,EAAK,GACrE,IAAO,IAAe,IAAW,IAEjC,IAAU,EAAM,OAAO,CAAI;CACjC,EAAQ,UAAU;CAElB,IAAM,IAAU,EAAM,aACnB,MAAqD;EACpD,IAAM,IACJ,OAAO,KAAa,aAAa,EAAS,EAAQ,OAAO,IAAI;EAI/D,AAHK,KACH,GAAgB,CAAQ,GAE1B,IAAe,CAAQ;CACzB,GACA,CAAC,GAAc,CAAY,CAC7B,GAGM,CAAC,GAAO,KAAY,EAAM,SAAS,EAAE,GACrC,CAAC,GAAa,KAAkB,EAAM,SAAS,EAAE,GACjD,CAAC,IAAW,MAAgB,EAAM,SAAS,EAAE,GAC7C,CAAC,GAAW,MAAgB,EAAM,SAAS,EAAK,GAChD,CAAC,GAAO,MAAY,EAAM,SAAS,EAAK,GACxC,IAAW,EAAM,OAAyB,IAAI,GAC9C,KAAU,EAAM,OAAuB,IAAI,GAC3C,IAAa,EAAM,MAAM,GACzB,KAAY,uBAAuB,KAGnC,EAAE,eAAe,MAAc,EAAU,GACzC,IAAqB,EAAE,UAAU,EAAE,GAGnC,KAAQ,EAAM,cAAc,GAAS,GAAG,CAAC,CAAC,GAG1C,IAAe,EAAM,cAClB,MAAM,QAAQ,CAAW,IAAI,IAAc,CAAC,CAAW,GAC9D,CAAC,CAAW,CACd,GAGM,IAAY,EAAO,SAAS,GAG5B,IAAiB,EAAM,cAAc;EACzC,IAAI,CAAC,GAAW,OAAO,CAAC;EACxB,IAAI,CAAC,EAAM,KAAK,GAAG,OAAO;EAC1B,IAAM,IAAI,EAAM,YAAY;EAC5B,OAAO,EACJ,KAAK,OAAW;GACf,GAAG;GACH,OAAO,EAAM,MAAM,QAChB,MACC,GAAe,CAAI,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,KAC7C,GAAqB,CAAI,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CACvD;EACF,EAAE,CAAC,CACF,QAAQ,MAAU,EAAM,MAAM,SAAS,CAAC;CAC7C,GAAG;EAAC;EAAQ;EAAO;CAAS,CAAC,GAEvB,IAAgB,EAAM,cACpB,EAAe,SAAS,MAAM,EAAE,KAAK,GAC3C,CAAC,CAAc,CACjB,GAGM,KAAe,EAAM,cAAc;EACvC,IAAM,oBAAM,IAAI,IAAoB,GAChC,IAAM;EACV,KAAK,IAAM,KAAS,GAClB,KAAK,IAAM,KAAQ,EAAM,OACvB,EAAI,IAAI,EAAK,IAAI,GAAK;EAG1B,OAAO;CACT,GAAG,CAAC,CAAc,CAAC,GAGb,KACJ,OAAO,KAAc,WAAW,GAAG,EAAU,MAAM;CAiCrD,AA9BA,EAAM,gBAAgB;EACpB,IAAI,MAAY,cAAc,MAAe,IAAO;EAEpD,IAAM,IAAW,MAAM,QAAQ,CAAU,IAAI,IAAa,CAAC,CAAU;EAErE,SAAS,EAAc,GAAkB;GACvC,KAAK,IAAM,KAAW,GACpB,IAAI,GAAkB,GAAG,CAAO,GAAG;IAEjC,AADA,EAAE,eAAe,GACjB,GAAS,MAAS,CAAC,CAAI;IACvB;GACF;EAEJ;EAEA,OADA,SAAS,iBAAiB,WAAW,CAAa,SACrC,SAAS,oBAAoB,WAAW,CAAa;CACpE,GAAG;EAAC;EAAS;EAAY;CAAO,CAAC,GAGjC,EAAM,gBAAgB;EACpB,AAAI,MAAY,cAAc,MAC5B,EAAS,EAAE,GACX,EAAe,EAAE,GACjB,4BAA4B;GAC1B,EAAS,SAAS,MAAM;EAC1B,CAAC;CAEL,GAAG,CAAC,GAAS,CAAI,CAAC,GAGlB,EAAM,gBAAgB;EAChB,IAAc,MACD,GAAQ,SAAS,cAChC,wBAAwB,EAAY,GACtC,EAAA,EACU,eAAe,EAAE,OAAO,UAAU,CAAC;CAC/C,GAAG,CAAC,CAAW,CAAC;CAGhB,IAAM,MAAqB,MAAkB;EAG3C,AAFA,EAAS,CAAK,GACd,EAAe,KAAa,EAAM,KAAK,IAAI,IAAI,EAAE,GACjD,KAAW,CAAK;CAClB,GAGM,KAAe,EAAM,kBAAkB;EACvC,CAAC,EAAM,KAAK,KAAK,MACrB,GAAa,CAAK,GAClB,IAAW,CAAK;CAClB,GAAG;EAAC;EAAO;EAAU;CAAQ,CAAC,GAGxB,MAAiB,MAA2B;EAChD,QAAQ,EAAE,KAAV;GACE,KAAK;IACH,IAAI,CAAC,KAAa,EAAc,WAAW,GAAG;IAE9C,AADA,EAAE,eAAe,GACjB,GAAgB,MACd,IAAO,EAAc,SAAS,IAAI,IAAO,IAAI,CAC/C;IACA;GAEF,KAAK;IACH,AAAI,KAAa,EAAc,SAAS,KACtC,EAAE,eAAe,GACjB,GAAgB,MACd,IAAO,IAAI,IAAO,IAAI,EAAc,SAAS,CAC/C,KACS,CAAC,KAAa,CAAC,KAAS,OAEjC,EAAE,eAAe,GACjB,EAAS,EAAS;IAEpB;GAEF,KAAK;IAIH,AAHA,EAAE,eAAe,GACE,EAAE,WAAW,EAAE,UAIhC,GAAa,IAEb,KACA,KAAe,KACf,EAAc,MAGd,EAAc,EAAY,CAAC,SAAS,GAChC,MAAY,cAAY,EAAQ,EAAK,KAGzC,GAAa;IAEf;GAEF,KAAK;IAEH,AADA,EAAE,eAAe,GACb,MAAU,cACZ,EAAS,EAAE,IACF,MAAY,aACrB,EAAQ,EAAK,IAEb,EAAS,SAAS,KAAK;IAEzB;EAEJ;CACF,GAGM,WAAoB;EAGxB,AAFA,EAAS,EAAE,GACX,EAAe,EAAE,GACjB,EAAS,SAAS,MAAM;CAC1B;CAWqB,AARrB,EAAM,gBAAgB;EACpB,IAAI,GAAO;GACT,IAAM,IAAQ,iBAAiB,GAAS,EAAK,GAAG,GAAG;GACnD,aAAa,aAAa,CAAK;EACjC;CACF,GAAG,CAAC,CAAK,CAAC,GAGW,KAAiC,EAAQ;CAC9D,IAAM,IAAY,IAAY,IAAqB,EAAO,MACpD,IAAS,IAAY;EAAE,SAAS;EAAG,OAAO;EAAG,GAAG;CAAE,IAAI,KAAA,GAKtD,IAAY,MAAY,UACxB,IAAe,MAAU,cACzB,KAAc,MAAU,aAExB,UACJ,kBAAC,IAAD;EACE,QAAQ;EACR,SAAS,IAAY,oBAAoB;EACzC,eAAe;YAEf,kBAAC,OAAD;GACE,WAAW,EACT,uIACA,IACI,6BACA,4BACJ,IACI,uBACA,gCACJ,KAAa,CAAC,KAAgB,+BAC9B,KAAS,eACX;aAXF;IAcA,kBAAC,GAAD;KACE,MAAM;KACN,MAAM,IAAY,OAAO;KACzB,QAAO;KACP,WAAW,EACT,wEACA,IAAY,kBAAkB,wBAChC;IACD,CAAA;IAGD,kBAAC,OAAD;KAAK,WAAU;eAAf,CACG,CAAC,KAAS,CAAC,KAAa,EAAa,SAAS,KAC7C,kBAAC,IAAD;MACgB;MACd,UAAU;MACV,QAAQ,KAAa,CAAC,CAAC;KACxB,CAAA,GAEH,kBAAC,SAAD;MACE,KAAK;MACL,OAAO;MACP,WAAW,MAAM,GAAkB,EAAE,OAAO,KAAK;MACjD,eAAe,GAAa,EAAI;MAChC,cAAc,GAAa,EAAK;MAChC,WAAW;MACX,aACE,EAAa,WAAW,KAAK,IAAY,EAAa,KAAK;MAE7D,UAAU;MACA;MACV,MAAK;MACL,iBAAe,KAAa,EAAc,SAAS;MACnD,iBAAe,IAAY,KAAY,KAAA;MACvC,yBACE,KAAa,KAAe,KAAK,EAAc,KAC3C,oBAAoB,EAAW,GAAG,EAAc,EAAY,CAAC,OAC7D,KAAA;MAEN,qBAAmB,IAAY,SAAS,KAAA;MACxC,cAAY,IAAY,OAAO,MAAc;MAC7C,WAAW,EACT,wDACA,sCACA,IAAY,qBAAqB,qBACjC,KAAgB,eAChB,KAAY,+BACd;MACA,cAAa;MACb,aAAY;MACZ,YAAY;KACb,CAAA,CACE;;IAGJ,IACC,kBAAC,QAAD;KAAM,eAAY;KAAsB,WAAU;eAChD,kBAAC,GAAD;MACE,MAAM;MACN,MAAM,IAAY,OAAO;MACzB,QAAO;MACP,SAAQ;MACR,WAAU;KACX,CAAA;IACG,CAAA,IACJ,KACF,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;KACV,cAAW;KACX,OAAM;eAEN,kBAAC,GAAD;MACE,MAAM;MACN,MAAM,IAAY,OAAO;MACzB,QAAO;KACR,CAAA;IACK,CAAA,IACN,MAAY,SACd,kBAAC,GAAD,EAAA,UACG,CAAC,KACA,kBAAC,EAAO,KAAR;KACE,SAAS,KAAU,EAAE,SAAS,EAAE;KAChC,SAAS,EAAE,SAAS,EAAE;KACtB,MAAM,IAAY,KAAA,IAAY,EAAE,SAAS,EAAE;KAC3C,YAAY;KACZ,WAAU;eALZ,CAOG,GAAmB,EAAK,GAAE,GACjB;OAEC,CAAA,IACf;GACC;;CACa,CAAA,GAMhB,UACA,CAAC,KAKD,EAFF,EAAc,SAAS,KAAM,EAAM,KAAK,KAAK,EAAe,WAAW,MAErD,CAAC,EAAM,KAAK,IAAU,OAGxC,kBAAC,OAAD;EACE,KAAK;EACL,IAAI;EACJ,MAAK;EACL,cAAW;EACX,WAAU;EACV,OAAO,EAAE,WAAW,GAAe;YANrC,CAQG,EAAe,WAAW,KAAK,EAAM,KAAK,KACzC,kBAAC,EAAO,KAAR;GACE,SAAS,KAAU,EAAE,SAAS,EAAE;GAChC,SAAS,EAAE,SAAS,EAAE;GACtB,YAAY;GACZ,WAAU;aAET,MACC,kBAAC,KAAD;IAAG,WAAU;cACV;GACA,CAAA;EAEK,CAAA,GAGb,EAAe,KAAK,GAAO,MAC1B,kBAAC,EAAO,KAAR;GAEE,SAAS,KAAU,EAAE,SAAS,EAAE;GAChC,SAAS,EAAE,SAAS,EAAE;GACtB,YACE,IACI,IACA;IAAE,GAAG,EAAO;IAAM,OAAO,IAAW;GAAK;GAE/C,WAAU;aATZ,CAWE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,QAAD;KAAM,WAAU;eACb,EAAM;IACH,CAAA;GACH,CAAA,GAEJ,EAAM,MAAM,KAAK,MAAS;IACzB,IAAM,IAAY,GAAa,IAAI,EAAK,EAAE,KAAK,GACzC,IAAW,MAAc;IAC/B,OACE,kBAAC,EAAO,QAAR;KAEE,IAAI,oBAAoB,EAAW,GAAG,EAAK;KAC3C,MAAK;KACL,MAAK;KACL,iBAAe;KACf,sBAAoB;KACpB,SAAS,KAAU;MAAE,SAAS;MAAG,GAAG;KAAE;KACtC,SAAS;MAAE,SAAS;MAAG,GAAG;KAAE;KAC5B,YACE,IACI,IACA;MAAE,GAAG,EAAQ;MAAQ,OAAO,IAAY;KAAK;KAEnD,eAAe;MAEb,AADA,EAAK,SAAS,GACV,MAAY,cAAY,EAAQ,EAAK;KAC3C;KACA,oBAAoB,EAAe,CAAS;KAC5C,WAAW,EACT,gKACA,IACI,4CACA,+CACN;eAxBF;MA0BG,EAAK,QACJ,kBAAC,QAAD;OACE,WAAW,EACT,0GACA,IACI,mBACA,wBACN;OACA,eAAY;iBAEZ,kBAAC,GAAD;QAAc,MAAK;kBAAM,EAAc,EAAK,IAAI;OAAgB,CAAA;MAC5D,CAAA;MAER,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAK,cACF,EAAK,YAAY,CAAK,IACtB,EAAK;OACL,CAAA,GACL,EAAK,eACJ,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAK;OACF,CAAA,CAEL;;MACL,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,EAAO,MAAR;OACE,SAAS,IAAY,KAAA,IAAY,EAAE,SAAS,EAAE;OAC9C,SAAS,EAAE,SAAS,EAAE;OACtB,MAAM,IAAY,KAAA,IAAY,EAAE,SAAS,EAAE;OAC3C,YAAY;OACZ,WAAU;iBAEV,kBAAC,GAAD;QACE,MAAM;QACN,MAAK;QACL,QAAO;QACP,WAAU;OACX,CAAA;MACU,CAAA,EAEA,CAAA;KACJ;OApER,EAAK,EAoEG;GAEnB,CAAC,CACS;KA5FL,EAAM,KA4FD,CACb,CACE;;CA8ET,OAvEI,MAAY,SAEZ,kBAAC,OAAD;EACO;EACL,MAAK;EACL,WAAW,EACT,8DACA,CACF;EACA,GAAI;YAPN;GASG,KACC,kBAAC,KAAD;IAAG,WAAU;cACV;GACA,CAAA;GAGJ,EAAe;GACf,EAAqB;GAGrB,KAAS,EAAM,SAAS,KACvB,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAM,KAAK,MACV,kBAAC,UAAD;KAEE,MAAK;KACL,eAAe;MAGb,AAFA,EAAS,CAAI,GACb,KAAW,CAAI,GACf,EAAS,SAAS,MAAM;KAC1B;KACA,WAAU;eAET;IACK,GAVD,CAUC,CACT;GACE,CAAA;GAIN,KAAY,kBAAC,OAAD;IAAK,WAAU;IAAY;GAAc,CAAA;EACnD;MAOL,MAAY,WAEZ,kBAAC,OAAD;EACO;EACL,MAAK;EACL,WAAW,EAAG,UAAU,CAAS;EACjC,GAAI;YAJN;GAMG,EAAe;GACf,EAAqB;GACrB,KAAY,kBAAC,OAAD;IAAK,WAAU;IAAY;GAAc,CAAA;EACnD;MAYP,kBAAC,GAAD;EAAc;EAAM,eALU,MAAsB;GACpD,EAAQ,CAAQ;EAClB;YAII,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAe,WAAU,6JAA8J,CAAA,GACvL,kBAAC,IAAD;GACO;GACL,GAAI;GACJ,WAAW,EACT,0EACA,wEACA,qFACA,8DACA,gEACA,sFACA,gFACA,CACF;aAZF;IAcE,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UAAa,iBAA2B,CAAA,GACxC,kBAAC,IAAD,EAAA,UAAmB,oCAEA,CAAA,CACL,EAAA,CAAA;IAEhB,kBAAC,OAAD;KAAK,WAAU;eAAW,EAAe;IAAO,CAAA;IAE/C,EAAqB;IAErB,KACC,kBAAC,OAAD;KAAK,WAAU;KACZ;IACE,CAAA;IAIP,kBAAC,EAAO,KAAR;KACE,SAAS,KAAU,EAAE,SAAS,EAAE;KAChC,SAAS,EAAE,SAAS,EAAE;KACtB,YAAY;KACZ,WAAU;eAJZ;MAMG,KACC,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD;UAAM,MAAM;UAAa,MAAK;UAAK,WAAU;SAA0B,CAAA;QACpE,CAAA,GACL,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD;UAAM,MAAM;UAAe,MAAK;UAAK,WAAU;SAA0B,CAAA;QACtE,CAAA,CACF;WACL,kBAAC,QAAD;QAAM,WAAU;kBAAsC;OAEhD,CAAA,CACH;;MAEP,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD;SAAM,MAAM;SAAoB,MAAK;SAAK,WAAU;QAA0B,CAAA;OAC3E,CAAA,GACL,kBAAC,QAAD;QAAM,WAAU;kBAAsC;OAEhD,CAAA,CACH;;MACL,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAoL;OAE9L,CAAA,GACL,kBAAC,QAAD;QAAM,WAAU;kBAAsC;OAEhD,CAAA,CACH;;KACK;;GACI;IACN,EAAA,CAAA;CACR,CAAA;AAEZ,CACF;AAEA,EAAW,cAAc"}
|
package/dist/ai/conversation.js
CHANGED
|
@@ -3,8 +3,8 @@ import { IconProvider as e } from "../ui/icon-context.js";
|
|
|
3
3
|
import { durations as t, springs as n } from "../ui/lib/motion.js";
|
|
4
4
|
import { cn as r } from "../ui/lib/utils.js";
|
|
5
5
|
import { Icon as i } from "../ui/icon.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { useMotion as a } from "../_chunks/motion-provider.js";
|
|
7
|
+
import { normalizeIcon as o } from "../_chunks/normalize-icon.js";
|
|
8
8
|
import { useAICommand as s } from "./ai-command-provider.js";
|
|
9
9
|
import { BlockRenderer as c } from "./block-renderer.js";
|
|
10
10
|
import * as l from "react";
|
|
@@ -52,7 +52,7 @@ function y({ name: t, icon: n }) {
|
|
|
52
52
|
className: "h-4 w-4 flex items-center justify-center",
|
|
53
53
|
children: /* @__PURE__ */ u(e, {
|
|
54
54
|
size: "sm",
|
|
55
|
-
children:
|
|
55
|
+
children: o(n)
|
|
56
56
|
})
|
|
57
57
|
}), /* @__PURE__ */ u("span", {
|
|
58
58
|
className: "text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle",
|
|
@@ -180,8 +180,8 @@ function C({ onClick: e }) {
|
|
|
180
180
|
children: ["↓", " New response"]
|
|
181
181
|
});
|
|
182
182
|
}
|
|
183
|
-
var w = { name: "Assistant" }, T = l.forwardRef(({ messages: e, isProcessing: t = !1, processingSteps: n, agent: i, onAction:
|
|
184
|
-
let _ = s(), { reducedMotion: v } =
|
|
183
|
+
var w = { name: "Assistant" }, T = l.forwardRef(({ messages: e, isProcessing: t = !1, processingSteps: n, agent: i, onAction: o, customBlocks: c, maxHeight: f, autoScroll: p = !0, className: m }, h) => {
|
|
184
|
+
let _ = s(), { reducedMotion: v } = a(), y = i ?? _?.agent ?? w, T = o ?? _?.onAction, E = l.useMemo(() => ({
|
|
185
185
|
..._?.customBlocks ?? {},
|
|
186
186
|
...c
|
|
187
187
|
}), [_?.customBlocks, c]), D = l.useRef(null), O = l.useRef(null), [k, A] = l.useState(!0), [j, M] = l.useState(!1), N = l.useRef(e.length), P = l.useRef(t);
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { VariantProps } from 'class-variance-authority';
|
|
3
|
-
import { AvatarRing } from '../ui/avatar';
|
|
3
|
+
import { avatarVariants, AvatarRing } from '../ui/avatar';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
|
|
6
|
-
size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
|
|
7
|
-
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
5
|
+
type Size = NonNullable<VariantProps<typeof avatarVariants>['size']>;
|
|
8
6
|
export interface AvatarUser {
|
|
9
7
|
name: string;
|
|
10
8
|
image?: string | null;
|
|
11
9
|
ring?: AvatarRing;
|
|
10
|
+
/** Small top-right marker. `lead` = accent dot, `admin` = warning dot, or any node. */
|
|
12
11
|
indicator?: 'lead' | 'admin' | React.ReactNode;
|
|
13
12
|
}
|
|
14
|
-
export interface AvatarGroupProps extends React.HTMLAttributes<HTMLDivElement
|
|
13
|
+
export interface AvatarGroupProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
15
14
|
users: AvatarUser[];
|
|
16
15
|
max?: number;
|
|
16
|
+
size?: Size;
|
|
17
17
|
showTooltip?: boolean;
|
|
18
18
|
/** Border color for the group avatars. @default 'surface-raised' */
|
|
19
19
|
borderColor?: 'surface-base' | 'surface-raised';
|
|
20
|
-
/** Callback when the "+N" overflow badge is clicked */
|
|
20
|
+
/** Callback when the "+N" overflow badge is clicked (renders it as a button). */
|
|
21
21
|
onOverflowClick?: () => void;
|
|
22
|
-
/** Custom render function for each avatar */
|
|
22
|
+
/** Custom render function for each avatar (consumer owns the Avatar). */
|
|
23
23
|
renderAvatar?: (user: AvatarUser, index: number) => React.ReactNode;
|
|
24
|
-
/** Direction avatars expand on hover. @default 'right' */
|
|
24
|
+
/** Direction avatars expand on hover/focus. @default 'right' */
|
|
25
25
|
expandDirection?: 'left' | 'right';
|
|
26
|
-
/** How
|
|
26
|
+
/** How far avatars spread on hover/focus. @default 'default' */
|
|
27
27
|
expandAmount?: 'compact' | 'default' | 'wide';
|
|
28
|
+
/** Accessible label for the group. @default `${count} team members` */
|
|
29
|
+
label?: string;
|
|
28
30
|
}
|
|
29
31
|
declare const AvatarGroup: React.ForwardRefExoticComponent<AvatarGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
30
32
|
export { AvatarGroup };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar-group.d.ts","sourceRoot":"","sources":["../../src/composed/avatar-group.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"avatar-group.d.ts","sourceRoot":"","sources":["../../src/composed/avatar-group.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAIL,cAAc,EACd,KAAK,UAAU,EAChB,MAAM,cAAc,CAAA;AAWrB,KAAK,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AAWpE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC,SAAS,CAAA;CAC/C;AAED,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5E,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,oEAAoE;IACpE,WAAW,CAAC,EAAE,cAAc,GAAG,gBAAgB,CAAA;IAC/C,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,yEAAyE;IACzE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IACnE,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAClC,gEAAgE;IAChE,YAAY,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;IAC7C,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAiBD,QAAA,MAAM,WAAW,yFA4KhB,CAAA;AAGD,OAAO,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -1,159 +1,127 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { springs as e } from "../ui/lib/motion.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import { AnimatePresence as m, motion as h } from "framer-motion";
|
|
3
|
+
import { cn as t } from "../ui/lib/utils.js";
|
|
4
|
+
import { Avatar as n, AvatarFallback as r, AvatarImage as i } from "../ui/avatar.js";
|
|
5
|
+
import { Tooltip as a, TooltipContent as o, TooltipProvider as s, TooltipTrigger as c } from "../ui/tooltip.js";
|
|
6
|
+
import { getInitials as l } from "./lib/string-utils.js";
|
|
7
|
+
import * as u from "react";
|
|
8
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
9
|
+
import { motion as p, useReducedMotion as m } from "framer-motion";
|
|
11
10
|
//#region src/composed/avatar-group.tsx
|
|
12
|
-
var
|
|
13
|
-
lead: "ring-2 ring-accent-7
|
|
14
|
-
admin: "ring-2 ring-warning-7
|
|
15
|
-
client: "ring-2 ring-info-7
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}[y ?? "md"], N = {
|
|
39
|
-
xs: "h-1 w-1",
|
|
40
|
-
sm: "h-1.5 w-1.5",
|
|
41
|
-
md: "h-2 w-2",
|
|
42
|
-
lg: "h-2.5 w-2.5",
|
|
43
|
-
xl: "h-3 w-3"
|
|
44
|
-
}[y ?? "md"], P = x === "surface-base" ? "border-surface-base" : "border-surface-raised", [F, I] = d.useState(!1), L = {
|
|
45
|
-
xs: 8,
|
|
46
|
-
sm: 10,
|
|
47
|
-
md: 12,
|
|
48
|
-
lg: 16,
|
|
49
|
-
xl: 20
|
|
50
|
-
}[y ?? "md"], R = {
|
|
11
|
+
var h = {
|
|
12
|
+
lead: "ring-2 ring-accent-7",
|
|
13
|
+
admin: "ring-2 ring-warning-7",
|
|
14
|
+
client: "ring-2 ring-info-7"
|
|
15
|
+
}, g = {
|
|
16
|
+
xs: "-ml-ds-02",
|
|
17
|
+
sm: "-ml-ds-02b",
|
|
18
|
+
md: "-ml-ds-03",
|
|
19
|
+
lg: "-ml-ds-04",
|
|
20
|
+
xl: "-ml-ds-05"
|
|
21
|
+
}, _ = {
|
|
22
|
+
xs: 8,
|
|
23
|
+
sm: 10,
|
|
24
|
+
md: 12,
|
|
25
|
+
lg: 16,
|
|
26
|
+
xl: 20
|
|
27
|
+
}, v = {
|
|
28
|
+
xs: "size-1",
|
|
29
|
+
sm: "size-1.5",
|
|
30
|
+
md: "size-2",
|
|
31
|
+
lg: "size-2.5",
|
|
32
|
+
xl: "size-3"
|
|
33
|
+
}, y = u.forwardRef(({ users: y, max: b = 4, size: x = "md", showTooltip: S = !0, borderColor: C = "surface-raised", onOverflowClick: w, renderAvatar: T, expandDirection: E = "right", expandAmount: D = "default", label: O, className: k, onMouseEnter: A, onMouseLeave: j, onFocus: M, onBlur: N, ...P }, F) => {
|
|
34
|
+
let I = m(), [L, R] = u.useState(!1);
|
|
35
|
+
if (y.length === 0) return null;
|
|
36
|
+
let z = Math.max(1, b), B = y.slice(0, z), V = y.length - z, H = g[x], U = C === "surface-base" ? "border-surface-base" : "border-surface-raised", W = C === "surface-base" ? "ring-offset-1 ring-offset-surface-base" : "ring-offset-1 ring-offset-surface-raised", G = _[x], K = {
|
|
51
37
|
compact: .5,
|
|
52
38
|
default: 1,
|
|
53
39
|
wide: 1.5
|
|
54
|
-
}[
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return /* @__PURE__ */ f(c, { children: /* @__PURE__ */ p("div", {
|
|
62
|
-
ref: O,
|
|
40
|
+
}[D], q = B.length + +(V > 0), J = (e) => {
|
|
41
|
+
if (!L || I) return 0;
|
|
42
|
+
let t = G * K;
|
|
43
|
+
return E === "left" ? -(q - 1 - e) * t : e * t;
|
|
44
|
+
}, Y = I ? { duration: 0 } : e.snappy, X = "transition-opacity duration-fast-02 ease-productive-standard motion-reduce:transition-none hover:z-30 focus-visible:z-30 group-hover:[&:not(:hover)]:opacity-80";
|
|
45
|
+
return /* @__PURE__ */ d(s, { children: /* @__PURE__ */ f("div", {
|
|
46
|
+
ref: F,
|
|
63
47
|
role: "group",
|
|
64
|
-
"aria-label": `${
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
48
|
+
"aria-label": O ?? `${y.length} team members`,
|
|
49
|
+
className: t("group flex items-center", k),
|
|
50
|
+
onMouseEnter: (e) => {
|
|
51
|
+
R(!0), A?.(e);
|
|
52
|
+
},
|
|
53
|
+
onMouseLeave: (e) => {
|
|
54
|
+
R(!1), j?.(e);
|
|
55
|
+
},
|
|
56
|
+
onFocus: (e) => {
|
|
57
|
+
R(!0), M?.(e);
|
|
58
|
+
},
|
|
70
59
|
onBlur: (e) => {
|
|
71
|
-
e.currentTarget.contains(e.relatedTarget) ||
|
|
60
|
+
e.currentTarget.contains(e.relatedTarget) || R(!1), N?.(e);
|
|
72
61
|
},
|
|
73
|
-
...
|
|
74
|
-
children: [
|
|
75
|
-
let
|
|
76
|
-
|
|
77
|
-
className:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
opacity: 0
|
|
104
|
-
},
|
|
105
|
-
animate: {
|
|
106
|
-
scale: 1,
|
|
107
|
-
opacity: 1
|
|
108
|
-
},
|
|
109
|
-
exit: {
|
|
110
|
-
scale: 0,
|
|
111
|
-
opacity: 0
|
|
112
|
-
},
|
|
113
|
-
transition: e.snappy,
|
|
114
|
-
className: n("absolute top-0 right-0 rounded-pill ring-1 ring-surface-raised", N, t.indicator === "lead" || t.indicator === "admin" ? "bg-accent-9" : ""),
|
|
115
|
-
children: typeof t.indicator != "string" && t.indicator
|
|
116
|
-
}) })]
|
|
117
|
-
}, _);
|
|
118
|
-
return b ? /* @__PURE__ */ p(o, { children: [/* @__PURE__ */ f(l, {
|
|
62
|
+
...P,
|
|
63
|
+
children: [B.map((e, s) => {
|
|
64
|
+
let m = `${e.name}-${s}`, g = e.ring && e.ring !== "none" ? t(h[e.ring], W) : void 0, _ = T ? T(e, s) : /* @__PURE__ */ f(n, {
|
|
65
|
+
size: x,
|
|
66
|
+
className: U,
|
|
67
|
+
children: [
|
|
68
|
+
e.image && /* @__PURE__ */ d(i, {
|
|
69
|
+
src: e.image,
|
|
70
|
+
alt: ""
|
|
71
|
+
}),
|
|
72
|
+
/* @__PURE__ */ d(r, {
|
|
73
|
+
colorSeed: e.name,
|
|
74
|
+
children: l(e.name)
|
|
75
|
+
}),
|
|
76
|
+
e.indicator && /* @__PURE__ */ d("span", {
|
|
77
|
+
"aria-hidden": "true",
|
|
78
|
+
className: t("absolute top-0 right-0 rounded-pill ring-1 ring-surface-raised", v[x], e.indicator === "lead" ? "bg-accent-9" : e.indicator === "admin" ? "bg-warning-9" : ""),
|
|
79
|
+
children: typeof e.indicator != "string" && e.indicator
|
|
80
|
+
})
|
|
81
|
+
]
|
|
82
|
+
}), y = /* @__PURE__ */ d(p.button, {
|
|
83
|
+
type: "button",
|
|
84
|
+
"aria-label": e.name,
|
|
85
|
+
animate: { x: J(s) },
|
|
86
|
+
transition: Y,
|
|
87
|
+
style: { zIndex: B.length - s },
|
|
88
|
+
className: t("relative shrink-0 rounded-pill focus-ring", s > 0 && H, X, g),
|
|
89
|
+
children: _
|
|
90
|
+
});
|
|
91
|
+
return S ? /* @__PURE__ */ f(a, { children: [/* @__PURE__ */ d(c, {
|
|
119
92
|
asChild: !0,
|
|
120
|
-
children:
|
|
121
|
-
}), /* @__PURE__ */
|
|
122
|
-
className: "border-surface-border-strong bg-surface-base text-surface-fg",
|
|
93
|
+
children: y
|
|
94
|
+
}), /* @__PURE__ */ d(o, {
|
|
123
95
|
sideOffset: 6,
|
|
124
|
-
children: /* @__PURE__ */
|
|
96
|
+
children: /* @__PURE__ */ d("p", {
|
|
125
97
|
className: "text-body-sm",
|
|
126
|
-
children:
|
|
98
|
+
children: e.name
|
|
127
99
|
})
|
|
128
|
-
})] },
|
|
129
|
-
}),
|
|
100
|
+
})] }, m) : /* @__PURE__ */ d(u.Fragment, { children: y }, m);
|
|
101
|
+
}), V > 0 && /* @__PURE__ */ f(a, { children: [/* @__PURE__ */ d(c, {
|
|
130
102
|
asChild: !0,
|
|
131
|
-
children:
|
|
103
|
+
children: /* @__PURE__ */ d(p.button, {
|
|
132
104
|
type: "button",
|
|
133
|
-
onClick:
|
|
134
|
-
"aria-label": `${
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
transform: B(k.length)
|
|
148
|
-
},
|
|
149
|
-
children: ["+", A]
|
|
105
|
+
onClick: w,
|
|
106
|
+
"aria-label": `${V} more ${V === 1 ? "member" : "members"}`,
|
|
107
|
+
animate: { x: J(B.length) },
|
|
108
|
+
transition: Y,
|
|
109
|
+
style: { zIndex: 0 },
|
|
110
|
+
className: t("relative shrink-0 rounded-pill focus-ring", H, X, !w && "cursor-default"),
|
|
111
|
+
children: /* @__PURE__ */ d(n, {
|
|
112
|
+
size: x,
|
|
113
|
+
className: U,
|
|
114
|
+
children: /* @__PURE__ */ f(r, {
|
|
115
|
+
className: "bg-accent-2 font-semibold text-accent-11",
|
|
116
|
+
children: ["+", V]
|
|
117
|
+
})
|
|
118
|
+
})
|
|
150
119
|
})
|
|
151
|
-
}), /* @__PURE__ */
|
|
152
|
-
className: "border-surface-border-strong bg-surface-base text-surface-fg",
|
|
120
|
+
}), /* @__PURE__ */ d(o, {
|
|
153
121
|
sideOffset: 6,
|
|
154
|
-
children: /* @__PURE__ */
|
|
122
|
+
children: /* @__PURE__ */ d("div", {
|
|
155
123
|
className: "flex flex-col gap-ds-01",
|
|
156
|
-
children:
|
|
124
|
+
children: y.slice(z).map((e, t) => /* @__PURE__ */ d("p", {
|
|
157
125
|
className: "text-body-sm",
|
|
158
126
|
children: e.name
|
|
159
127
|
}, t))
|
|
@@ -161,6 +129,6 @@ var g = {
|
|
|
161
129
|
})] })]
|
|
162
130
|
}) });
|
|
163
131
|
});
|
|
164
|
-
|
|
132
|
+
y.displayName = "AvatarGroup";
|
|
165
133
|
//#endregion
|
|
166
|
-
export {
|
|
134
|
+
export { y as AvatarGroup };
|