@stackone/malachite 2.37.1 → 2.38.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 (94) hide show
  1. package/COMPONENTS.md +7 -2
  2. package/dist/assets/icons/account.svg.js +2 -2
  3. package/dist/assets/icons/account.svg.js.map +1 -1
  4. package/dist/assets/icons/building.svg.js +6 -0
  5. package/dist/assets/icons/building.svg.js.map +1 -0
  6. package/dist/assets/icons/chevrons_up_down.svg.js +6 -0
  7. package/dist/assets/icons/chevrons_up_down.svg.js.map +1 -0
  8. package/dist/assets/icons/connector.svg.js +6 -0
  9. package/dist/assets/icons/connector.svg.js.map +1 -0
  10. package/dist/assets/icons/external_link.svg.js +6 -0
  11. package/dist/assets/icons/external_link.svg.js.map +1 -0
  12. package/dist/assets/icons/field_coverage.svg.js +6 -0
  13. package/dist/assets/icons/field_coverage.svg.js.map +1 -0
  14. package/dist/assets/icons/layout.svg.js +6 -0
  15. package/dist/assets/icons/layout.svg.js.map +1 -0
  16. package/dist/assets/icons/link.svg.js +6 -0
  17. package/dist/assets/icons/link.svg.js.map +1 -0
  18. package/dist/assets/icons/playground.svg.js +6 -0
  19. package/dist/assets/icons/playground.svg.js.map +1 -0
  20. package/dist/components/ActionMenu.js +139 -170
  21. package/dist/components/ActionMenu.js.map +1 -1
  22. package/dist/components/Chat/ChatModelPicker.js +64 -60
  23. package/dist/components/Chat/ChatModelPicker.js.map +1 -1
  24. package/dist/components/CustomIcons/BuildingIcon.js +16 -0
  25. package/dist/components/CustomIcons/BuildingIcon.js.map +1 -0
  26. package/dist/components/CustomIcons/ChevronsUpDownIcon.js +16 -0
  27. package/dist/components/CustomIcons/ChevronsUpDownIcon.js.map +1 -0
  28. package/dist/components/CustomIcons/ConnectorIcon.js +16 -0
  29. package/dist/components/CustomIcons/ConnectorIcon.js.map +1 -0
  30. package/dist/components/CustomIcons/ExternalLinkIcon.js +16 -0
  31. package/dist/components/CustomIcons/ExternalLinkIcon.js.map +1 -0
  32. package/dist/components/CustomIcons/FieldCoverageIcon.js +16 -0
  33. package/dist/components/CustomIcons/FieldCoverageIcon.js.map +1 -0
  34. package/dist/components/CustomIcons/LayoutIcon.js +16 -0
  35. package/dist/components/CustomIcons/LayoutIcon.js.map +1 -0
  36. package/dist/components/CustomIcons/LinkIcon.js +16 -0
  37. package/dist/components/CustomIcons/LinkIcon.js.map +1 -0
  38. package/dist/components/CustomIcons/PlaygroundIcon.js +16 -0
  39. package/dist/components/CustomIcons/PlaygroundIcon.js.map +1 -0
  40. package/dist/components/CustomIcons/index.js +303 -279
  41. package/dist/components/CustomIcons/index.js.map +1 -1
  42. package/dist/components/NavItem.js +158 -0
  43. package/dist/components/NavItem.js.map +1 -0
  44. package/dist/components/Popover.js +262 -0
  45. package/dist/components/Popover.js.map +1 -0
  46. package/dist/components/PopoverParts.js +46 -0
  47. package/dist/components/PopoverParts.js.map +1 -0
  48. package/dist/components/QueryInput.js +103 -97
  49. package/dist/components/QueryInput.js.map +1 -1
  50. package/dist/components/SearchTrigger.js +37 -0
  51. package/dist/components/SearchTrigger.js.map +1 -0
  52. package/dist/components/Sidebar.js +174 -0
  53. package/dist/components/Sidebar.js.map +1 -0
  54. package/dist/components/Tooltip.js +97 -92
  55. package/dist/components/Tooltip.js.map +1 -1
  56. package/dist/components/UsageCard.js +44 -0
  57. package/dist/components/UsageCard.js.map +1 -0
  58. package/dist/components/actionMenuKeyboard.js +23 -0
  59. package/dist/components/actionMenuKeyboard.js.map +1 -0
  60. package/dist/components/actionMenuStyles.js +83 -0
  61. package/dist/components/actionMenuStyles.js.map +1 -0
  62. package/dist/components/ariaState.js +5 -0
  63. package/dist/components/ariaState.js.map +1 -0
  64. package/dist/components/chromeStyles.js +6 -0
  65. package/dist/components/chromeStyles.js.map +1 -0
  66. package/dist/components/composeRefs.js +27 -0
  67. package/dist/components/composeRefs.js.map +1 -0
  68. package/dist/components/floatingMenuGeometry.js +74 -35
  69. package/dist/components/floatingMenuGeometry.js.map +1 -1
  70. package/dist/components/overlayBehaviour.js +90 -84
  71. package/dist/components/overlayBehaviour.js.map +1 -1
  72. package/dist/components/popoverTree.js +14 -0
  73. package/dist/components/popoverTree.js.map +1 -0
  74. package/dist/components/portalOverlay.js +28 -22
  75. package/dist/components/portalOverlay.js.map +1 -1
  76. package/dist/components/sidebarContext.js +9 -0
  77. package/dist/components/sidebarContext.js.map +1 -0
  78. package/dist/components/topLayer.js +18 -18
  79. package/dist/components/topLayer.js.map +1 -1
  80. package/dist/components/useActionMenuPosition.js +73 -0
  81. package/dist/components/useActionMenuPosition.js.map +1 -0
  82. package/dist/components/useHoverClose.js +18 -0
  83. package/dist/components/useHoverClose.js.map +1 -0
  84. package/dist/components/useLatestRef.js +11 -0
  85. package/dist/components/useLatestRef.js.map +1 -0
  86. package/dist/components/usePopoverPosition.js +62 -0
  87. package/dist/components/usePopoverPosition.js.map +1 -0
  88. package/dist/components/usePopoverTree.js +34 -0
  89. package/dist/components/usePopoverTree.js.map +1 -0
  90. package/dist/index.d.ts +387 -100
  91. package/dist/index.js +365 -335
  92. package/dist/index.js.map +1 -1
  93. package/dist/tailwind.css.js +1 -1
  94. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ActionMenu.js","sources":["../../src/components/ActionMenu.tsx"],"sourcesContent":["import React, {\n useState,\n useRef,\n useEffect,\n useInsertionEffect,\n useLayoutEffect,\n useCallback,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport Button from './Button';\nimport type { ButtonVariant } from './Button';\nimport MoreHorizontalIcon from './CustomIcons/MoreHorizontalIcon';\nimport { pushEscapeLayer } from './escapeLayers';\nimport {\n MENU_SPECS,\n type MenuGeometry,\n measureContentWidth,\n measureMenuGeometry,\n} from './floatingMenuGeometry';\nimport { ensureOverlayStyles, overlayIdentity } from './portalOverlay';\nimport { useTopLayer } from './topLayer';\n\nconst LABEL_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n};\n\nconst EMPTY_ITEM_STYLE: React.CSSProperties = {\n padding: '6px 10px',\n fontSize: 'var(--malachite-font-size-small, 13px)',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n userSelect: 'none',\n};\n\nexport type ActionMenuItem =\n | {\n type?: 'item';\n key: string;\n label: React.ReactNode;\n onClick?: () => void;\n disabled?: boolean;\n danger?: boolean;\n tooltip?: string;\n icon?: React.ReactNode;\n }\n | {\n type: 'divider';\n key: string;\n };\n\nexport interface ActionMenuProps {\n items: ActionMenuItem[];\n label?: string;\n triggerIcon?: React.ReactNode;\n minWidth?: number;\n size?: 'small' | 'xsmall';\n /**\n * Shows `label` beside the icon instead of leaving it to the accessible name. For a menu\n * that is the point of its corner rather than an overflow for a row that already reads —\n * a kebab nobody can name is only safe when the row it belongs to says what it acts on.\n */\n showLabel?: boolean;\n /** Trigger's Button variant. Defaults to `outline`, the overflow-kebab look. */\n variant?: ButtonVariant;\n}\n\n// No box here: pinning `--malachite-control-height-small` beat Button's own `size-[28px]`, so a\n// theme that moved that token moved the kebab and left the Button behind. Only the glyph is\n// left to size, Button sizing one only for its `icon` prop.\nconst TRIGGER_SIZES: Record<'small' | 'xsmall', { icon: number; iconBox: string }> = {\n small: { icon: 16, iconBox: 'text-[16px] [&_svg]:size-[16px]!' },\n xsmall: { icon: 11, iconBox: 'text-[11px] [&_svg]:size-[11px]!' },\n};\n\nconst itemStyle = (item: ActionMenuItem): React.CSSProperties => {\n if (item.type === 'divider') {\n return {\n height: 1,\n background: 'var(--malachite-card-border, rgb(232, 232, 232))',\n margin: '4px 0',\n };\n }\n return {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 10px',\n borderRadius: 8,\n fontSize: 'var(--malachite-font-size-small, 13px)',\n fontWeight: 400,\n color: item.danger\n ? 'var(--malachite-text-destructive, rgb(237, 53, 54))'\n : 'var(--malachite-text-primary, rgb(10, 10, 10))',\n cursor: item.disabled ? 'not-allowed' : 'pointer',\n opacity: item.disabled ? 0.5 : 1,\n userSelect: 'none',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n background: 'transparent',\n border: 'none',\n textAlign: 'left',\n width: '100%',\n };\n};\n\n/**\n * ActionMenu is a kebab-style overflow action menu. The trigger is a square\n * icon-only outline Button (three-dot icon by default); on click, a popover\n * appears with the given items. The popover is rendered to document.body via\n * createPortal so it escapes any Shadow DOM or overflow:hidden ancestors —\n * which is also why the popover is styled inline rather than with Tailwind:\n * the scoped stylesheet does not reach document.body.\n */\nconst ActionMenu: React.FC<ActionMenuProps> = ({\n items,\n label = 'More actions',\n triggerIcon,\n minWidth,\n size = 'small',\n showLabel = false,\n variant = 'outline',\n}) => {\n const trigger = TRIGGER_SIZES[size];\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState<MenuGeometry | null>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const contentWidthRef = useRef<number | undefined>(undefined);\n\n useTopLayer(popoverRef, open);\n\n const updatePosition = useCallback(() => {\n const trigger = triggerRef.current;\n if (!trigger) {\n return;\n }\n contentWidthRef.current =\n measureContentWidth(popoverRef.current) ?? contentWidthRef.current;\n\n setPosition(\n measureMenuGeometry(popoverRef.current, {\n triggerRect: trigger.getBoundingClientRect(),\n preset: 'options',\n minWidth,\n contentWidth: contentWidthRef.current,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n }),\n );\n }, [minWidth]);\n\n useEffect(() => {\n if (!open) {\n setPosition(null);\n contentWidthRef.current = undefined;\n return;\n }\n updatePosition();\n const handleScrollOrResize = () => updatePosition();\n const handleClickOutside = (e: MouseEvent) => {\n const target = e.target as Node;\n if (!triggerRef.current?.contains(target) && !popoverRef.current?.contains(target)) {\n setOpen(false);\n }\n };\n // ESC via the shared layer stack: closes only the topmost overlay.\n const popEscapeLayer = pushEscapeLayer(() => setOpen(false));\n window.addEventListener('scroll', handleScrollOrResize, true);\n window.addEventListener('resize', handleScrollOrResize);\n document.addEventListener('mousedown', handleClickOutside, true);\n return () => {\n window.removeEventListener('scroll', handleScrollOrResize, true);\n window.removeEventListener('resize', handleScrollOrResize);\n document.removeEventListener('mousedown', handleClickOutside, true);\n popEscapeLayer();\n };\n }, [open, updatePosition]);\n\n useLayoutEffect(() => {\n if (open && popoverRef.current) {\n updatePosition();\n }\n }, [open, updatePosition]);\n\n const handleItemClick = (item: ActionMenuItem) => {\n if (item.type === 'divider' || item.disabled) {\n return;\n }\n item.onClick?.();\n setOpen(false);\n };\n\n useInsertionEffect(() => {\n if (open) {\n ensureOverlayStyles();\n }\n }, [open]);\n\n const popoverStyle: React.CSSProperties = {\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n width: position?.width,\n maxHeight: position?.maxHeight,\n overflowY: 'auto',\n background: MENU_SPECS.options.background,\n border: MENU_SPECS.options.border,\n borderRadius: MENU_SPECS.options.radius,\n boxShadow: MENU_SPECS.options.shadow,\n padding: MENU_SPECS.options.padding,\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n visibility: position ? 'visible' : 'hidden',\n opacity: position ? 1 : 0,\n };\n\n return (\n <>\n <Button\n ref={triggerRef}\n type=\"button\"\n variant={variant}\n size={size}\n iconOnly={!showLabel}\n // With the label drawn, it is already the accessible name; repeating it here\n // would have a screen reader announce it twice.\n aria-label={showLabel ? undefined : label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n // The engaged border while open is each variant's own, keyed off aria-expanded\n // in the stylesheet — pinning the outline token here stripped it from every\n // other variant.\n //\n // Button only spaces the icon it owns via its `icon` prop; this one is a child,\n // so the gap is set here rather than left to collapse against the label. `gap-2`\n // because the stylesheet is precompiled: a utility no source file already uses\n // is never emitted, and the class then does nothing with nothing to show for it.\n className={`shrink-0${showLabel ? ' gap-2' : ''}`}\n onClick={(e) => {\n e.stopPropagation();\n setOpen((v) => !v);\n }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n {/* `!important` because every CustomIcon writes its size inline; `text-[…]` for a\n glyph that is not an svg at all, which the svg rule never matches. */}\n <span className={`inline-flex items-center justify-center ${trigger.iconBox}`}>\n {triggerIcon ?? <MoreHorizontalIcon size={trigger.icon} />}\n </span>\n {showLabel && <span>{label}</span>}\n </Button>\n {open &&\n createPortal(\n <div\n ref={popoverRef}\n role=\"menu\"\n {...overlayIdentity('actionmenu')}\n style={popoverStyle}\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n >\n {items.length === 0 && (\n // role=\"menu\" takes menuitem children only, so the notice is one.\n <div role=\"menuitem\" aria-disabled=\"true\" style={EMPTY_ITEM_STYLE}>\n No actions available\n </div>\n )}\n {items.map((item) =>\n item.type === 'divider' ? (\n <div key={item.key} style={itemStyle(item)} />\n ) : (\n <button\n key={item.key}\n type=\"button\"\n role=\"menuitem\"\n disabled={item.disabled}\n title={item.tooltip}\n onClick={() => handleItemClick(item)}\n onMouseEnter={(e) => {\n if (!item.disabled) {\n (\n e.currentTarget as HTMLButtonElement\n ).style.background = 'rgba(0, 0, 0, 0.04)';\n }\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background =\n 'transparent';\n }}\n style={itemStyle(item)}\n >\n {/* Leading: every caller's icon names the action itself —\n copy, open, delete — and an icon that is part of an\n item's identity belongs where the eye starts, not\n right-aligned where it reads as a status column. */}\n {item.icon && (\n <span\n style={{\n display: 'inline-flex',\n flexShrink: 0,\n color: 'var(--malachite-icon-secondary, rgb(148, 148, 148))',\n }}\n >\n {item.icon}\n </span>\n )}\n <span style={LABEL_STYLE}>{item.label}</span>\n </button>\n ),\n )}\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default ActionMenu;\n"],"names":["LABEL_STYLE","EMPTY_ITEM_STYLE","TRIGGER_SIZES","itemStyle","item","ActionMenu","items","label","triggerIcon","minWidth","size","showLabel","variant","trigger","open","setOpen","useState","position","setPosition","triggerRef","useRef","popoverRef","contentWidthRef","useTopLayer","updatePosition","useCallback","measureContentWidth","measureMenuGeometry","useEffect","handleScrollOrResize","handleClickOutside","e","target","_a","_b","popEscapeLayer","pushEscapeLayer","useLayoutEffect","handleItemClick","useInsertionEffect","ensureOverlayStyles","popoverStyle","MENU_SPECS","jsxs","Fragment","Button","v","jsx","MoreHorizontalIcon","createPortal","overlayIdentity"],"mappings":"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"}
1
+ {"version":3,"file":"ActionMenu.js","sources":["../../src/components/ActionMenu.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport Button from './Button';\nimport type { ButtonVariant } from './Button';\nimport MoreHorizontalIcon from './CustomIcons/MoreHorizontalIcon';\nimport {\n type MenuEdge,\n edgeForTriggerKey,\n enabledItems,\n focusEdge,\n itemForMenuKey,\n} from './actionMenuKeyboard';\nimport {\n EMPTY_ITEM_STYLE,\n ITEM_CLASS,\n ITEM_ICON_STYLE,\n LABEL_STYLE,\n TEXT_ITEM_STYLE,\n TRIGGER_SIZES,\n type ActionMenuTone,\n itemStyle,\n menuStyle,\n} from './actionMenuStyles';\nimport type { ActionMenuItem, ActionMenuPlacement } from './actionMenuTypes';\nimport { getDeepActiveElement } from './activeElement';\nimport { chainHandler, composeRefs, elementRef } from './composeRefs';\nimport { pushEscapeLayer } from './escapeLayers';\nimport type { FloatingOffset } from './floatingMenuGeometry';\nimport { overlayIdentity } from './portalOverlay';\nimport { useActionMenuPosition } from './useActionMenuPosition';\n\nexport type { ActionMenuItem, ActionMenuPlacement, ActionMenuTone };\n\nexport interface ActionMenuProps {\n items: ActionMenuItem[];\n label?: string;\n triggerIcon?: React.ReactNode;\n minWidth?: number;\n size?: 'small' | 'xsmall';\n /**\n * Shows `label` beside the icon instead of leaving it to the accessible name. For a menu\n * that is the point of its corner rather than an overflow for a row that already reads —\n * a kebab nobody can name is only safe when the row it belongs to says what it acts on.\n */\n showLabel?: boolean;\n /** Trigger's Button variant. Defaults to `outline`, the overflow-kebab look. */\n variant?: ButtonVariant;\n trigger?: React.ReactElement;\n placement?: ActionMenuPlacement;\n offset?: FloatingOffset;\n /** `muted` reads items in the secondary text colour, as in a sidebar's menus. */\n tone?: ActionMenuTone;\n}\n\ntype TriggerHandlers = {\n onClick?: (event: React.MouseEvent) => void;\n onMouseDown?: (event: React.MouseEvent) => void;\n onKeyDown?: (event: React.KeyboardEvent) => void;\n};\n\nconst stopPropagation = (event: React.SyntheticEvent) => event.stopPropagation();\n\nconst MenuItemRow: React.FC<{\n item: ActionMenuItem;\n tone: ActionMenuTone;\n onSelect: (item: ActionMenuItem) => void;\n}> = ({ item, tone, onSelect }) => {\n if (item.type === 'divider') {\n return <div style={itemStyle(item)} />;\n }\n if (item.type === 'text') {\n return (\n <div role=\"menuitem\" aria-disabled=\"true\" style={TEXT_ITEM_STYLE}>\n {item.label}\n </div>\n );\n }\n return (\n <button\n type=\"button\"\n role=\"menuitem\"\n disabled={item.disabled}\n title={item.tooltip}\n className={ITEM_CLASS}\n onClick={() => onSelect(item)}\n style={itemStyle(item, tone)}\n >\n {item.icon && <span style={ITEM_ICON_STYLE}>{item.icon}</span>}\n <span style={LABEL_STYLE}>{item.label}</span>\n </button>\n );\n};\n\n/**\n * ActionMenu is an overflow action menu. The trigger is a three-dot `Button` by default, or\n * your own control via `trigger`. The menu is portaled to document.body, so it escapes any\n * Shadow DOM or overflow:hidden ancestor, which is also why it is styled inline.\n */\nconst ActionMenu: React.FC<ActionMenuProps> = ({\n items,\n label = 'More actions',\n triggerIcon,\n minWidth,\n size = 'small',\n showLabel = false,\n variant = 'outline',\n trigger: customTrigger,\n placement = 'bottom-end',\n offset,\n tone = 'default',\n}) => {\n const triggerSize = TRIGGER_SIZES[size];\n const [open, setOpen] = useState(false);\n const triggerRef = useRef<HTMLElement | null>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const focusOnOpen = useRef<MenuEdge | null>(null);\n const focusInMenu = useRef(false);\n\n const position = useActionMenuPosition(open, triggerRef, menuRef, {\n minWidth,\n placement,\n offset,\n });\n\n useEffect(() => {\n if (!open) {\n return;\n }\n if (focusOnOpen.current) {\n focusEdge(menuRef.current, focusOnOpen.current);\n focusOnOpen.current = null;\n }\n const closeOnOutsidePress = (event: MouseEvent) => {\n const path = event.composedPath();\n const inside = [triggerRef.current, menuRef.current].some(\n (node) => node && path.includes(node),\n );\n if (!inside) {\n focusInMenu.current = false;\n setOpen(false);\n }\n };\n document.addEventListener('mousedown', closeOnOutsidePress, true);\n const popEscapeLayer = pushEscapeLayer(() => setOpen(false));\n return () => {\n document.removeEventListener('mousedown', closeOnOutsidePress, true);\n popEscapeLayer();\n const active = getDeepActiveElement();\n if (focusInMenu.current && (!active || active === document.body)) {\n triggerRef.current?.focus({ preventScroll: true });\n }\n focusInMenu.current = false;\n };\n }, [open]);\n\n const toggleFromTrigger = (event: React.MouseEvent) => {\n event.stopPropagation();\n const openedFromKeyboard = !open && event.detail === 0;\n focusOnOpen.current = openedFromKeyboard ? 'first' : null;\n setOpen((v) => !v);\n };\n\n const handleTriggerKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Tab' && open) {\n setOpen(false);\n return;\n }\n const edge = edgeForTriggerKey(event.key, placement);\n if (!edge) {\n return;\n }\n event.preventDefault();\n if (open) {\n focusEdge(menuRef.current, edge);\n return;\n }\n focusOnOpen.current = edge;\n setOpen(true);\n };\n\n const handleMenuKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Tab') {\n focusInMenu.current = false;\n triggerRef.current?.focus({ preventScroll: true });\n setOpen(false);\n return;\n }\n const target = itemForMenuKey(enabledItems(menuRef.current), event.target, event.key);\n if (target) {\n event.preventDefault();\n target.focus();\n }\n };\n\n const selectItem = (item: ActionMenuItem) => {\n if (item.type === 'divider' || item.type === 'text' || item.disabled) {\n return;\n }\n item.onClick?.();\n setOpen(false);\n };\n\n const ownTriggerRef = customTrigger ? elementRef<HTMLElement>(customTrigger) : undefined;\n const composedTriggerRef = useMemo(\n () => composeRefs(ownTriggerRef, triggerRef),\n [ownTriggerRef],\n );\n const customHandlers = customTrigger?.props as TriggerHandlers | undefined;\n\n const triggerElement = customTrigger ? (\n React.cloneElement(customTrigger, {\n ref: composedTriggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: chainHandler(customHandlers?.onClick, toggleFromTrigger),\n onMouseDown: chainHandler(customHandlers?.onMouseDown, stopPropagation),\n onKeyDown: chainHandler(customHandlers?.onKeyDown, handleTriggerKeyDown),\n } as Record<string, unknown>)\n ) : (\n <Button\n ref={triggerRef as React.RefObject<HTMLButtonElement>}\n type=\"button\"\n variant={variant}\n size={size}\n iconOnly={!showLabel}\n aria-label={showLabel ? undefined : label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className={`shrink-0${showLabel ? ' gap-2' : ''}`}\n onClick={toggleFromTrigger}\n onMouseDown={stopPropagation}\n onKeyDown={handleTriggerKeyDown}\n >\n <span className={`inline-flex items-center justify-center ${triggerSize.iconBox}`}>\n {triggerIcon ?? <MoreHorizontalIcon size={triggerSize.icon} />}\n </span>\n {showLabel && <span>{label}</span>}\n </Button>\n );\n\n return (\n <>\n {triggerElement}\n {open &&\n createPortal(\n <div\n ref={menuRef}\n role=\"menu\"\n tabIndex={-1}\n aria-label={label}\n {...overlayIdentity('actionmenu')}\n style={menuStyle(position)}\n onMouseDown={stopPropagation}\n onClick={stopPropagation}\n onKeyDown={handleMenuKeyDown}\n onFocus={() => {\n focusInMenu.current = true;\n }}\n onBlur={(e) => {\n if (!menuRef.current?.contains(e.relatedTarget as Node | null)) {\n focusInMenu.current = false;\n }\n }}\n >\n {items.length === 0 && (\n <div role=\"menuitem\" aria-disabled=\"true\" style={EMPTY_ITEM_STYLE}>\n No actions available\n </div>\n )}\n {items.map((item) => (\n <MenuItemRow key={item.key} item={item} tone={tone} onSelect={selectItem} />\n ))}\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default ActionMenu;\n"],"names":["stopPropagation","event","MenuItemRow","item","tone","onSelect","jsx","itemStyle","TEXT_ITEM_STYLE","jsxs","ITEM_CLASS","ITEM_ICON_STYLE","LABEL_STYLE","ActionMenu","items","label","triggerIcon","minWidth","size","showLabel","variant","customTrigger","placement","offset","triggerSize","TRIGGER_SIZES","open","setOpen","useState","triggerRef","useRef","menuRef","focusOnOpen","focusInMenu","position","useActionMenuPosition","useEffect","focusEdge","closeOnOutsidePress","path","node","popEscapeLayer","pushEscapeLayer","active","getDeepActiveElement","_a","toggleFromTrigger","openedFromKeyboard","v","handleTriggerKeyDown","edge","edgeForTriggerKey","handleMenuKeyDown","target","itemForMenuKey","enabledItems","selectItem","ownTriggerRef","elementRef","composedTriggerRef","useMemo","composeRefs","customHandlers","triggerElement","React","chainHandler","Button","MoreHorizontalIcon","Fragment","createPortal","overlayIdentity","menuStyle","EMPTY_ITEM_STYLE"],"mappings":"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"}
@@ -1,16 +1,17 @@
1
- import { jsxs as g, Fragment as k, jsx as n } from "react/jsx-runtime";
2
- import { useState as x, useRef as I, useCallback as q, useEffect as J, useInsertionEffect as Q } from "react";
1
+ import { jsxs as g, Fragment as T, jsx as n } from "react/jsx-runtime";
2
+ import { useState as x, useRef as C, useCallback as k, useEffect as J, useInsertionEffect as Q } from "react";
3
3
  import { createPortal as X } from "react-dom";
4
- import { Avatar as O } from "../Avatar.js";
4
+ import { Avatar as B } from "../Avatar.js";
5
5
  import Z from "../CustomIcons/CaretDownIcon.js";
6
6
  import ee from "../CustomIcons/CaretRightIcon.js";
7
7
  import te from "../CustomIcons/CaretUpIcon.js";
8
8
  import D from "../CustomIcons/CheckIcon.js";
9
9
  import { PillButton as ne } from "../PillButton.js";
10
10
  import { pushEscapeLayer as re } from "../escapeLayers.js";
11
- import { ensureOverlayStyles as ie, overlayIdentity as M } from "../portalOverlay.js";
12
- import { useTopLayer as oe } from "../topLayer.js";
13
- const h = 8, _ = 220, C = 240, B = (r, a) => ({
11
+ import { useOwnedByPopover as ie } from "../popoverTree.js";
12
+ import { ensureOverlayStyles as oe, overlayIdentity as M } from "../portalOverlay.js";
13
+ import { useTopLayer as le } from "../topLayer.js";
14
+ const h = 8, _ = 220, z = 240, N = (r, a) => ({
14
15
  position: "fixed",
15
16
  top: (r == null ? void 0 : r.top) ?? 0,
16
17
  left: (r == null ? void 0 : r.left) ?? 0,
@@ -25,7 +26,7 @@ const h = 8, _ = 220, C = 240, B = (r, a) => ({
25
26
  gap: 2,
26
27
  visibility: r ? "visible" : "hidden",
27
28
  opacity: r ? 1 : 0
28
- }), N = {
29
+ }), W = {
29
30
  display: "flex",
30
31
  alignItems: "center",
31
32
  gap: 8,
@@ -38,89 +39,92 @@ const h = 8, _ = 220, C = 240, B = (r, a) => ({
38
39
  cursor: "pointer",
39
40
  fontSize: "var(--malachite-font-size-small, 13px)",
40
41
  color: "var(--malachite-text-primary, rgb(10, 10, 10))"
41
- }, le = {
42
+ }, se = {
42
43
  fontSize: "var(--malachite-font-size-xsmall, 11px)",
43
44
  color: "var(--malachite-text-dimmed, rgb(161, 161, 161))"
44
- }, W = {
45
+ }, A = {
45
46
  marginLeft: "auto",
46
47
  display: "inline-flex",
47
48
  color: "var(--malachite-text-success, rgb(2, 122, 66))"
48
- }, ye = ({
49
+ }, Ee = ({
49
50
  models: r,
50
51
  value: a,
51
- optionValue: A,
52
- onChange: H,
53
- disabled: F = !1,
52
+ optionValue: H,
53
+ onChange: F,
54
+ disabled: U = !1,
54
55
  openUp: y = !0,
55
- "aria-label": U = "Model"
56
+ "aria-label": Y = "Model"
56
57
  }) => {
57
- var T;
58
- const [f, b] = x(!1), [Y, j] = x(null), [G, w] = x(null), [K, z] = x(
58
+ var O;
59
+ const [c, b] = x(!1), [j, G] = x(null), [K, w] = x(null), [V, R] = x(
59
60
  null
60
- ), E = I(null), d = I(null), R = I(null);
61
- oe(d, f);
62
- const l = r.find((e) => e.value === a), L = q(() => {
61
+ ), E = C(null), d = C(null), L = C(null);
62
+ le(d, c), ie(
63
+ k(() => L.current, []),
64
+ c
65
+ );
66
+ const l = r.find((e) => e.value === a), S = k(() => {
63
67
  const e = E.current, t = d.current;
64
68
  if (!e)
65
69
  return;
66
- const i = e.getBoundingClientRect(), o = (t == null ? void 0 : t.offsetWidth) || _, s = (t == null ? void 0 : t.offsetHeight) || 0, v = window.innerWidth - o - h, u = Math.max(h, Math.min(i.right - o, v)), m = i.top - s - 4, p = i.bottom + 4, V = m >= h, $ = s === 0 || p + s <= window.innerHeight - h;
67
- j({ top: y ? V ? m : p : $ ? p : m, left: u });
70
+ const i = e.getBoundingClientRect(), o = (t == null ? void 0 : t.offsetWidth) || _, s = (t == null ? void 0 : t.offsetHeight) || 0, v = window.innerWidth - o - h, f = Math.max(h, Math.min(i.right - o, v)), m = i.top - s - 4, p = i.bottom + 4, $ = m >= h, q = s === 0 || p + s <= window.innerHeight - h;
71
+ G({ top: y ? $ ? m : p : q ? p : m, left: f });
68
72
  }, [y]);
69
73
  J(() => {
70
- if (!f) {
71
- w(null), z(null);
74
+ if (!c) {
75
+ w(null), R(null);
72
76
  return;
73
77
  }
74
- L();
75
- const e = () => L(), t = (o) => {
78
+ S();
79
+ const e = () => S(), t = (o) => {
76
80
  const s = o.composedPath();
77
- [E.current, d.current, R.current].some(
78
- (u) => u !== null && s.includes(u)
81
+ [E.current, d.current, L.current].some(
82
+ (f) => f !== null && s.includes(f)
79
83
  ) || b(!1);
80
84
  }, i = re(() => b(!1));
81
85
  return window.addEventListener("scroll", e, !0), window.addEventListener("resize", e), document.addEventListener("mousedown", t, !0), () => {
82
86
  window.removeEventListener("scroll", e, !0), window.removeEventListener("resize", e), document.removeEventListener("mousedown", t, !0), i();
83
87
  };
84
- }, [f, L]), Q(() => {
85
- f && ie();
86
- }, [f]);
88
+ }, [c, S]), Q(() => {
89
+ c && oe();
90
+ }, [c]);
87
91
  const P = (e, t) => {
88
- var u, m, p;
89
- if (!((u = e.options) != null && u.length)) {
92
+ var f, m, p;
93
+ if (!((f = e.options) != null && f.length)) {
90
94
  w(null);
91
95
  return;
92
96
  }
93
- const i = t.getBoundingClientRect(), s = (((m = d.current) == null ? void 0 : m.getBoundingClientRect().left) ?? i.left) - C - 4, v = s >= h ? s : Math.min(
97
+ const i = t.getBoundingClientRect(), s = (((m = d.current) == null ? void 0 : m.getBoundingClientRect().left) ?? i.left) - z - 4, v = s >= h ? s : Math.min(
94
98
  (((p = d.current) == null ? void 0 : p.getBoundingClientRect().right) ?? i.right) + 4,
95
- window.innerWidth - C - h
99
+ window.innerWidth - z - h
96
100
  );
97
- w(e.value), z({ top: i.top, left: v });
98
- }, S = (e, t) => {
99
- H(e.value, t == null ? void 0 : t.value), b(!1);
100
- }, c = r.find((e) => e.value === G);
101
- return /* @__PURE__ */ g(k, { children: [
101
+ w(e.value), R({ top: i.top, left: v });
102
+ }, I = (e, t) => {
103
+ F(e.value, t == null ? void 0 : t.value), b(!1);
104
+ }, u = r.find((e) => e.value === K);
105
+ return /* @__PURE__ */ g(T, { children: [
102
106
  /* @__PURE__ */ n("div", { ref: E, className: "inline-flex", children: /* @__PURE__ */ n(
103
107
  ne,
104
108
  {
105
109
  label: (l == null ? void 0 : l.label) ?? a,
106
- icon: l != null && l.iconSrc ? /* @__PURE__ */ n(O, { src: l.iconSrc, name: l.label, size: 14 }) : void 0,
110
+ icon: l != null && l.iconSrc ? /* @__PURE__ */ n(B, { src: l.iconSrc, name: l.label, size: 14 }) : void 0,
107
111
  trailingIcon: y ? /* @__PURE__ */ n(te, { size: 10 }) : /* @__PURE__ */ n(Z, { size: 10 }),
108
112
  shape: "tab",
109
113
  size: "small",
110
- disabled: F,
114
+ disabled: U,
111
115
  onClick: () => b((e) => !e)
112
116
  }
113
117
  ) }),
114
- f && X(
115
- /* @__PURE__ */ g(k, { children: [
118
+ c && X(
119
+ /* @__PURE__ */ g(T, { children: [
116
120
  /* @__PURE__ */ n(
117
121
  "div",
118
122
  {
119
123
  ref: d,
120
124
  role: "menu",
121
- "aria-label": U,
125
+ "aria-label": Y,
122
126
  ...M("actionmenu"),
123
- style: B(Y, _),
127
+ style: N(j, _),
124
128
  children: r.map((e) => {
125
129
  var t, i;
126
130
  return /* @__PURE__ */ g(
@@ -129,17 +133,17 @@ const h = 8, _ = 220, C = 240, B = (r, a) => ({
129
133
  type: "button",
130
134
  role: "menuitem",
131
135
  "aria-haspopup": (t = e.options) != null && t.length ? "menu" : void 0,
132
- style: N,
136
+ style: W,
133
137
  onMouseEnter: (o) => P(e, o.currentTarget),
134
138
  onFocus: (o) => P(e, o.currentTarget),
135
139
  onClick: () => {
136
140
  var o;
137
- return (o = e.options) != null && o.length ? S(e, e.options[0]) : S(e);
141
+ return (o = e.options) != null && o.length ? I(e, e.options[0]) : I(e);
138
142
  },
139
143
  children: [
140
- e.iconSrc ? /* @__PURE__ */ n(O, { src: e.iconSrc, name: e.label, size: 14 }) : null,
144
+ e.iconSrc ? /* @__PURE__ */ n(B, { src: e.iconSrc, name: e.label, size: 14 }) : null,
141
145
  e.label,
142
- e.value === a ? /* @__PURE__ */ n("span", { style: W, children: /* @__PURE__ */ n(D, { size: 11 }) }) : null,
146
+ e.value === a ? /* @__PURE__ */ n("span", { style: A, children: /* @__PURE__ */ n(D, { size: 11 }) }) : null,
143
147
  (i = e.options) != null && i.length ? /* @__PURE__ */ n(
144
148
  "span",
145
149
  {
@@ -158,21 +162,21 @@ const h = 8, _ = 220, C = 240, B = (r, a) => ({
158
162
  })
159
163
  }
160
164
  ),
161
- (T = c == null ? void 0 : c.options) != null && T.length ? /* @__PURE__ */ n(
165
+ (O = u == null ? void 0 : u.options) != null && O.length ? /* @__PURE__ */ n(
162
166
  "div",
163
167
  {
164
- ref: R,
168
+ ref: L,
165
169
  role: "menu",
166
- "aria-label": `${c.label} options`,
170
+ "aria-label": `${u.label} options`,
167
171
  ...M("actionmenu"),
168
- style: B(K, C),
169
- children: c.options.map((e) => /* @__PURE__ */ g(
172
+ style: N(V, z),
173
+ children: u.options.map((e) => /* @__PURE__ */ g(
170
174
  "button",
171
175
  {
172
176
  type: "button",
173
177
  role: "menuitem",
174
- style: { ...N, alignItems: "flex-start" },
175
- onClick: () => S(c, e),
178
+ style: { ...W, alignItems: "flex-start" },
179
+ onClick: () => I(u, e),
176
180
  children: [
177
181
  /* @__PURE__ */ g(
178
182
  "span",
@@ -184,11 +188,11 @@ const h = 8, _ = 220, C = 240, B = (r, a) => ({
184
188
  },
185
189
  children: [
186
190
  e.label,
187
- e.description ? /* @__PURE__ */ n("span", { style: le, children: e.description }) : null
191
+ e.description ? /* @__PURE__ */ n("span", { style: se, children: e.description }) : null
188
192
  ]
189
193
  }
190
194
  ),
191
- c.value === a && e.value === A ? /* @__PURE__ */ n("span", { style: W, children: /* @__PURE__ */ n(D, { size: 11 }) }) : null
195
+ u.value === a && e.value === H ? /* @__PURE__ */ n("span", { style: A, children: /* @__PURE__ */ n(D, { size: 11 }) }) : null
192
196
  ]
193
197
  },
194
198
  e.value
@@ -201,7 +205,7 @@ const h = 8, _ = 220, C = 240, B = (r, a) => ({
201
205
  ] });
202
206
  };
203
207
  export {
204
- ye as ChatModelPicker,
205
- ye as default
208
+ Ee as ChatModelPicker,
209
+ Ee as default
206
210
  };
207
211
  //# sourceMappingURL=ChatModelPicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatModelPicker.js","sources":["../../../src/components/Chat/ChatModelPicker.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useInsertionEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport Avatar from '../Avatar';\nimport CaretDownIcon from '../CustomIcons/CaretDownIcon';\nimport CaretRightIcon from '../CustomIcons/CaretRightIcon';\nimport CaretUpIcon from '../CustomIcons/CaretUpIcon';\nimport CheckIcon from '../CustomIcons/CheckIcon';\nimport PillButton from '../PillButton';\nimport { pushEscapeLayer } from '../escapeLayers';\nimport { ensureOverlayStyles, overlayIdentity } from '../portalOverlay';\nimport { useTopLayer } from '../topLayer';\n\nexport interface ChatModelSubOption {\n value: string;\n label: string;\n description?: string;\n}\n\nexport interface ChatModelOption {\n value: string;\n label: string;\n /** The provider's mark. A URL, since providers ship logos rather than icon fonts. */\n iconSrc?: string;\n /** A second choice the model offers, e.g. how long it may think. */\n options?: ChatModelSubOption[];\n}\n\nexport interface ChatModelPickerProps {\n models: ChatModelOption[];\n value: string;\n /** The chosen sub-option, when the current model offers them. */\n optionValue?: string;\n /** Called with the model, and its sub-option when it has them. */\n onChange: (model: string, option?: string) => void;\n disabled?: boolean;\n /**\n * Opens upward. On by default: this sits under a composer at the bottom of a column, so\n * downward is almost always off-screen.\n */\n openUp?: boolean;\n 'aria-label'?: string;\n}\n\nconst VIEWPORT_PADDING = 8;\nconst PANEL_MIN_WIDTH = 220;\nconst SUBMENU_MIN_WIDTH = 240;\n\n/**\n * Inline rather than Tailwind: the panel is portalled to `document.body`, which the scoped\n * shadow stylesheet does not reach. Same reason `ActionMenu` styles its popover inline.\n */\nconst panelStyle = (\n position: { top: number; left: number } | null,\n minWidth: number,\n): React.CSSProperties => ({\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n minWidth,\n background: 'var(--malachite-card-background, rgb(255, 255, 255))',\n border: '1px solid var(--malachite-card-border, rgb(232, 232, 232))',\n borderRadius: 12,\n boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.08)',\n padding: 4,\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n visibility: position ? 'visible' : 'hidden',\n opacity: position ? 1 : 0,\n});\n\nconst ROW_STYLE: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 10px',\n borderRadius: 8,\n border: 'none',\n background: 'transparent',\n textAlign: 'left',\n width: '100%',\n cursor: 'pointer',\n fontSize: 'var(--malachite-font-size-small, 13px)',\n color: 'var(--malachite-text-primary, rgb(10, 10, 10))',\n};\n\nconst DESCRIPTION_STYLE: React.CSSProperties = {\n fontSize: 'var(--malachite-font-size-xsmall, 11px)',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n};\n\nconst CHECK_STYLE: React.CSSProperties = {\n marginLeft: 'auto',\n display: 'inline-flex',\n color: 'var(--malachite-text-success, rgb(2, 122, 66))',\n};\n\n/**\n * Which model answers, and how hard it may think.\n *\n * Its own component rather than a `Dropdown`: that one is a form select bound to\n * react-hook-form, and this is a menu whose rows open a second menu. Portalled for the same\n * reason `ActionMenu` is — a panel inside the composer would be clipped by it.\n */\nconst ChatModelPicker: React.FC<ChatModelPickerProps> = ({\n models,\n value,\n optionValue,\n onChange,\n disabled = false,\n openUp = true,\n 'aria-label': ariaLabel = 'Model',\n}) => {\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState<{ top: number; left: number } | null>(null);\n const [submenuFor, setSubmenuFor] = useState<string | null>(null);\n const [submenuPosition, setSubmenuPosition] = useState<{ top: number; left: number } | null>(\n null,\n );\n const triggerRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const submenuRef = useRef<HTMLDivElement>(null);\n\n useTopLayer(panelRef, open);\n\n const selected = models.find((model) => model.value === value);\n\n const place = useCallback(() => {\n const trigger = triggerRef.current;\n const panel = panelRef.current;\n\n if (!trigger) {\n return;\n }\n\n const rect = trigger.getBoundingClientRect();\n const width = panel?.offsetWidth || PANEL_MIN_WIDTH;\n const height = panel?.offsetHeight || 0;\n const maxLeft = window.innerWidth - width - VIEWPORT_PADDING;\n const left = Math.max(VIEWPORT_PADDING, Math.min(rect.right - width, maxLeft));\n // Flips when the chosen side has no room, so the panel is never off-screen.\n const above = rect.top - height - 4;\n const below = rect.bottom + 4;\n const fitsAbove = above >= VIEWPORT_PADDING;\n const fitsBelow = height === 0 || below + height <= window.innerHeight - VIEWPORT_PADDING;\n const top = openUp ? (fitsAbove ? above : below) : fitsBelow ? below : above;\n\n setPosition({ top, left });\n }, [openUp]);\n\n useEffect(() => {\n if (!open) {\n setSubmenuFor(null);\n setSubmenuPosition(null);\n return;\n }\n\n place();\n\n const reposition = () => place();\n const closeOnOutside = (event: MouseEvent) => {\n // `composedPath`, not `event.target`: this listener is on `document`, and the\n // trigger lives in a shadow root, so the target is retargeted to the shadow HOST.\n // `contains` then says the trigger was not clicked, the menu closes on mousedown,\n // and the click that follows toggles it straight back open.\n const path = event.composedPath();\n const insideOwnUi = [triggerRef.current, panelRef.current, submenuRef.current].some(\n (node) => node !== null && path.includes(node),\n );\n\n if (!insideOwnUi) {\n setOpen(false);\n }\n };\n const popEscapeLayer = pushEscapeLayer(() => setOpen(false));\n\n window.addEventListener('scroll', reposition, true);\n window.addEventListener('resize', reposition);\n document.addEventListener('mousedown', closeOnOutside, true);\n\n return () => {\n window.removeEventListener('scroll', reposition, true);\n window.removeEventListener('resize', reposition);\n document.removeEventListener('mousedown', closeOnOutside, true);\n popEscapeLayer();\n };\n }, [open, place]);\n\n useInsertionEffect(() => {\n if (open) {\n ensureOverlayStyles();\n }\n }, [open]);\n\n const openSubmenu = (model: ChatModelOption, row: HTMLElement) => {\n if (!model.options?.length) {\n setSubmenuFor(null);\n return;\n }\n\n const rect = row.getBoundingClientRect();\n const panelLeft = panelRef.current?.getBoundingClientRect().left ?? rect.left;\n // To the left of the parent panel by default, flipping right when that would clip.\n const toLeft = panelLeft - SUBMENU_MIN_WIDTH - 4;\n const left =\n toLeft >= VIEWPORT_PADDING\n ? toLeft\n : Math.min(\n (panelRef.current?.getBoundingClientRect().right ?? rect.right) + 4,\n window.innerWidth - SUBMENU_MIN_WIDTH - VIEWPORT_PADDING,\n );\n\n setSubmenuFor(model.value);\n setSubmenuPosition({ top: rect.top, left });\n };\n\n const choose = (model: ChatModelOption, option?: ChatModelSubOption) => {\n onChange(model.value, option?.value);\n setOpen(false);\n };\n\n const submenuModel = models.find((model) => model.value === submenuFor);\n\n return (\n <>\n <div ref={triggerRef} className=\"inline-flex\">\n <PillButton\n label={selected?.label ?? value}\n icon={\n selected?.iconSrc ? (\n <Avatar src={selected.iconSrc} name={selected.label} size={14} />\n ) : undefined\n }\n trailingIcon={\n openUp ? (\n <CaretUpIcon size={10} />\n ) : (\n <CaretDownIcon size={10} />\n )\n }\n shape=\"tab\"\n size=\"small\"\n disabled={disabled}\n onClick={() => setOpen((wasOpen) => !wasOpen)}\n />\n </div>\n {open &&\n createPortal(\n <>\n <div\n ref={panelRef}\n role=\"menu\"\n aria-label={ariaLabel}\n // `actionmenu` rather than a new kind: the identity is a\n // host-facing allow-list, so a new class would need every host to\n // update its CSS, and this panel is an action menu in shape.\n {...overlayIdentity('actionmenu')}\n style={panelStyle(position, PANEL_MIN_WIDTH)}\n >\n {models.map((model) => (\n <button\n key={model.value}\n type=\"button\"\n role=\"menuitem\"\n aria-haspopup={model.options?.length ? 'menu' : undefined}\n style={ROW_STYLE}\n onMouseEnter={(event) =>\n openSubmenu(model, event.currentTarget)\n }\n onFocus={(event) => openSubmenu(model, event.currentTarget)}\n onClick={() =>\n model.options?.length\n ? choose(model, model.options[0])\n : choose(model)\n }\n >\n {model.iconSrc ? (\n <Avatar src={model.iconSrc} name={model.label} size={14} />\n ) : null}\n {model.label}\n {model.value === value ? (\n <span style={CHECK_STYLE}>\n <CheckIcon size={11} />\n </span>\n ) : null}\n {model.options?.length ? (\n <span\n style={{\n marginLeft: model.value === value ? 4 : 'auto',\n display: 'inline-flex',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n }}\n >\n <CaretRightIcon size={10} />\n </span>\n ) : null}\n </button>\n ))}\n </div>\n {submenuModel?.options?.length ? (\n <div\n ref={submenuRef}\n role=\"menu\"\n aria-label={`${submenuModel.label} options`}\n {...overlayIdentity('actionmenu')}\n style={panelStyle(submenuPosition, SUBMENU_MIN_WIDTH)}\n >\n {submenuModel.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitem\"\n style={{ ...ROW_STYLE, alignItems: 'flex-start' }}\n onClick={() => choose(submenuModel, option)}\n >\n <span\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n }}\n >\n {option.label}\n {option.description ? (\n <span style={DESCRIPTION_STYLE}>\n {option.description}\n </span>\n ) : null}\n </span>\n {submenuModel.value === value &&\n option.value === optionValue ? (\n <span style={CHECK_STYLE}>\n <CheckIcon size={11} />\n </span>\n ) : null}\n </button>\n ))}\n </div>\n ) : null}\n </>,\n document.body,\n )}\n </>\n );\n};\n\nexport default ChatModelPicker;\nexport { ChatModelPicker };\n"],"names":["VIEWPORT_PADDING","PANEL_MIN_WIDTH","SUBMENU_MIN_WIDTH","panelStyle","position","minWidth","ROW_STYLE","DESCRIPTION_STYLE","CHECK_STYLE","ChatModelPicker","models","value","optionValue","onChange","disabled","openUp","ariaLabel","open","setOpen","useState","setPosition","submenuFor","setSubmenuFor","submenuPosition","setSubmenuPosition","triggerRef","useRef","panelRef","submenuRef","useTopLayer","selected","model","place","useCallback","trigger","panel","rect","width","height","maxLeft","left","above","below","fitsAbove","fitsBelow","useEffect","reposition","closeOnOutside","event","path","node","popEscapeLayer","pushEscapeLayer","useInsertionEffect","ensureOverlayStyles","openSubmenu","row","_a","toLeft","_b","_c","choose","option","submenuModel","jsxs","Fragment","jsx","PillButton","Avatar","CaretUpIcon","CaretDownIcon","wasOpen","createPortal","overlayIdentity","CheckIcon","CaretRightIcon"],"mappings":"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"}
1
+ {"version":3,"file":"ChatModelPicker.js","sources":["../../../src/components/Chat/ChatModelPicker.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useInsertionEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport Avatar from '../Avatar';\nimport CaretDownIcon from '../CustomIcons/CaretDownIcon';\nimport CaretRightIcon from '../CustomIcons/CaretRightIcon';\nimport CaretUpIcon from '../CustomIcons/CaretUpIcon';\nimport CheckIcon from '../CustomIcons/CheckIcon';\nimport PillButton from '../PillButton';\nimport { pushEscapeLayer } from '../escapeLayers';\nimport { useOwnedByPopover } from '../popoverTree';\nimport { ensureOverlayStyles, overlayIdentity } from '../portalOverlay';\nimport { useTopLayer } from '../topLayer';\n\nexport interface ChatModelSubOption {\n value: string;\n label: string;\n description?: string;\n}\n\nexport interface ChatModelOption {\n value: string;\n label: string;\n /** The provider's mark. A URL, since providers ship logos rather than icon fonts. */\n iconSrc?: string;\n /** A second choice the model offers, e.g. how long it may think. */\n options?: ChatModelSubOption[];\n}\n\nexport interface ChatModelPickerProps {\n models: ChatModelOption[];\n value: string;\n /** The chosen sub-option, when the current model offers them. */\n optionValue?: string;\n /** Called with the model, and its sub-option when it has them. */\n onChange: (model: string, option?: string) => void;\n disabled?: boolean;\n /**\n * Opens upward. On by default: this sits under a composer at the bottom of a column, so\n * downward is almost always off-screen.\n */\n openUp?: boolean;\n 'aria-label'?: string;\n}\n\nconst VIEWPORT_PADDING = 8;\nconst PANEL_MIN_WIDTH = 220;\nconst SUBMENU_MIN_WIDTH = 240;\n\n/**\n * Inline rather than Tailwind: the panel is portalled to `document.body`, which the scoped\n * shadow stylesheet does not reach. Same reason `ActionMenu` styles its popover inline.\n */\nconst panelStyle = (\n position: { top: number; left: number } | null,\n minWidth: number,\n): React.CSSProperties => ({\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n minWidth,\n background: 'var(--malachite-card-background, rgb(255, 255, 255))',\n border: '1px solid var(--malachite-card-border, rgb(232, 232, 232))',\n borderRadius: 12,\n boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.08)',\n padding: 4,\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n visibility: position ? 'visible' : 'hidden',\n opacity: position ? 1 : 0,\n});\n\nconst ROW_STYLE: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 10px',\n borderRadius: 8,\n border: 'none',\n background: 'transparent',\n textAlign: 'left',\n width: '100%',\n cursor: 'pointer',\n fontSize: 'var(--malachite-font-size-small, 13px)',\n color: 'var(--malachite-text-primary, rgb(10, 10, 10))',\n};\n\nconst DESCRIPTION_STYLE: React.CSSProperties = {\n fontSize: 'var(--malachite-font-size-xsmall, 11px)',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n};\n\nconst CHECK_STYLE: React.CSSProperties = {\n marginLeft: 'auto',\n display: 'inline-flex',\n color: 'var(--malachite-text-success, rgb(2, 122, 66))',\n};\n\n/**\n * Which model answers, and how hard it may think.\n *\n * Its own component rather than a `Dropdown`: that one is a form select bound to\n * react-hook-form, and this is a menu whose rows open a second menu. Portalled for the same\n * reason `ActionMenu` is — a panel inside the composer would be clipped by it.\n */\nconst ChatModelPicker: React.FC<ChatModelPickerProps> = ({\n models,\n value,\n optionValue,\n onChange,\n disabled = false,\n openUp = true,\n 'aria-label': ariaLabel = 'Model',\n}) => {\n const [open, setOpen] = useState(false);\n const [position, setPosition] = useState<{ top: number; left: number } | null>(null);\n const [submenuFor, setSubmenuFor] = useState<string | null>(null);\n const [submenuPosition, setSubmenuPosition] = useState<{ top: number; left: number } | null>(\n null,\n );\n const triggerRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const submenuRef = useRef<HTMLDivElement>(null);\n\n useTopLayer(panelRef, open);\n useOwnedByPopover(\n useCallback(() => submenuRef.current, []),\n open,\n );\n\n const selected = models.find((model) => model.value === value);\n\n const place = useCallback(() => {\n const trigger = triggerRef.current;\n const panel = panelRef.current;\n\n if (!trigger) {\n return;\n }\n\n const rect = trigger.getBoundingClientRect();\n const width = panel?.offsetWidth || PANEL_MIN_WIDTH;\n const height = panel?.offsetHeight || 0;\n const maxLeft = window.innerWidth - width - VIEWPORT_PADDING;\n const left = Math.max(VIEWPORT_PADDING, Math.min(rect.right - width, maxLeft));\n // Flips when the chosen side has no room, so the panel is never off-screen.\n const above = rect.top - height - 4;\n const below = rect.bottom + 4;\n const fitsAbove = above >= VIEWPORT_PADDING;\n const fitsBelow = height === 0 || below + height <= window.innerHeight - VIEWPORT_PADDING;\n const top = openUp ? (fitsAbove ? above : below) : fitsBelow ? below : above;\n\n setPosition({ top, left });\n }, [openUp]);\n\n useEffect(() => {\n if (!open) {\n setSubmenuFor(null);\n setSubmenuPosition(null);\n return;\n }\n\n place();\n\n const reposition = () => place();\n const closeOnOutside = (event: MouseEvent) => {\n // `composedPath`, not `event.target`: this listener is on `document`, and the\n // trigger lives in a shadow root, so the target is retargeted to the shadow HOST.\n // `contains` then says the trigger was not clicked, the menu closes on mousedown,\n // and the click that follows toggles it straight back open.\n const path = event.composedPath();\n const insideOwnUi = [triggerRef.current, panelRef.current, submenuRef.current].some(\n (node) => node !== null && path.includes(node),\n );\n\n if (!insideOwnUi) {\n setOpen(false);\n }\n };\n const popEscapeLayer = pushEscapeLayer(() => setOpen(false));\n\n window.addEventListener('scroll', reposition, true);\n window.addEventListener('resize', reposition);\n document.addEventListener('mousedown', closeOnOutside, true);\n\n return () => {\n window.removeEventListener('scroll', reposition, true);\n window.removeEventListener('resize', reposition);\n document.removeEventListener('mousedown', closeOnOutside, true);\n popEscapeLayer();\n };\n }, [open, place]);\n\n useInsertionEffect(() => {\n if (open) {\n ensureOverlayStyles();\n }\n }, [open]);\n\n const openSubmenu = (model: ChatModelOption, row: HTMLElement) => {\n if (!model.options?.length) {\n setSubmenuFor(null);\n return;\n }\n\n const rect = row.getBoundingClientRect();\n const panelLeft = panelRef.current?.getBoundingClientRect().left ?? rect.left;\n // To the left of the parent panel by default, flipping right when that would clip.\n const toLeft = panelLeft - SUBMENU_MIN_WIDTH - 4;\n const left =\n toLeft >= VIEWPORT_PADDING\n ? toLeft\n : Math.min(\n (panelRef.current?.getBoundingClientRect().right ?? rect.right) + 4,\n window.innerWidth - SUBMENU_MIN_WIDTH - VIEWPORT_PADDING,\n );\n\n setSubmenuFor(model.value);\n setSubmenuPosition({ top: rect.top, left });\n };\n\n const choose = (model: ChatModelOption, option?: ChatModelSubOption) => {\n onChange(model.value, option?.value);\n setOpen(false);\n };\n\n const submenuModel = models.find((model) => model.value === submenuFor);\n\n return (\n <>\n <div ref={triggerRef} className=\"inline-flex\">\n <PillButton\n label={selected?.label ?? value}\n icon={\n selected?.iconSrc ? (\n <Avatar src={selected.iconSrc} name={selected.label} size={14} />\n ) : undefined\n }\n trailingIcon={\n openUp ? (\n <CaretUpIcon size={10} />\n ) : (\n <CaretDownIcon size={10} />\n )\n }\n shape=\"tab\"\n size=\"small\"\n disabled={disabled}\n onClick={() => setOpen((wasOpen) => !wasOpen)}\n />\n </div>\n {open &&\n createPortal(\n <>\n <div\n ref={panelRef}\n role=\"menu\"\n aria-label={ariaLabel}\n // `actionmenu` rather than a new kind: the identity is a\n // host-facing allow-list, so a new class would need every host to\n // update its CSS, and this panel is an action menu in shape.\n {...overlayIdentity('actionmenu')}\n style={panelStyle(position, PANEL_MIN_WIDTH)}\n >\n {models.map((model) => (\n <button\n key={model.value}\n type=\"button\"\n role=\"menuitem\"\n aria-haspopup={model.options?.length ? 'menu' : undefined}\n style={ROW_STYLE}\n onMouseEnter={(event) =>\n openSubmenu(model, event.currentTarget)\n }\n onFocus={(event) => openSubmenu(model, event.currentTarget)}\n onClick={() =>\n model.options?.length\n ? choose(model, model.options[0])\n : choose(model)\n }\n >\n {model.iconSrc ? (\n <Avatar src={model.iconSrc} name={model.label} size={14} />\n ) : null}\n {model.label}\n {model.value === value ? (\n <span style={CHECK_STYLE}>\n <CheckIcon size={11} />\n </span>\n ) : null}\n {model.options?.length ? (\n <span\n style={{\n marginLeft: model.value === value ? 4 : 'auto',\n display: 'inline-flex',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n }}\n >\n <CaretRightIcon size={10} />\n </span>\n ) : null}\n </button>\n ))}\n </div>\n {submenuModel?.options?.length ? (\n <div\n ref={submenuRef}\n role=\"menu\"\n aria-label={`${submenuModel.label} options`}\n {...overlayIdentity('actionmenu')}\n style={panelStyle(submenuPosition, SUBMENU_MIN_WIDTH)}\n >\n {submenuModel.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitem\"\n style={{ ...ROW_STYLE, alignItems: 'flex-start' }}\n onClick={() => choose(submenuModel, option)}\n >\n <span\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n }}\n >\n {option.label}\n {option.description ? (\n <span style={DESCRIPTION_STYLE}>\n {option.description}\n </span>\n ) : null}\n </span>\n {submenuModel.value === value &&\n option.value === optionValue ? (\n <span style={CHECK_STYLE}>\n <CheckIcon size={11} />\n </span>\n ) : null}\n </button>\n ))}\n </div>\n ) : null}\n </>,\n document.body,\n )}\n </>\n );\n};\n\nexport default ChatModelPicker;\nexport { ChatModelPicker };\n"],"names":["VIEWPORT_PADDING","PANEL_MIN_WIDTH","SUBMENU_MIN_WIDTH","panelStyle","position","minWidth","ROW_STYLE","DESCRIPTION_STYLE","CHECK_STYLE","ChatModelPicker","models","value","optionValue","onChange","disabled","openUp","ariaLabel","open","setOpen","useState","setPosition","submenuFor","setSubmenuFor","submenuPosition","setSubmenuPosition","triggerRef","useRef","panelRef","submenuRef","useTopLayer","useOwnedByPopover","useCallback","selected","model","place","trigger","panel","rect","width","height","maxLeft","left","above","below","fitsAbove","fitsBelow","useEffect","reposition","closeOnOutside","event","path","node","popEscapeLayer","pushEscapeLayer","useInsertionEffect","ensureOverlayStyles","openSubmenu","row","_a","toLeft","_b","_c","choose","option","submenuModel","jsxs","Fragment","jsx","PillButton","Avatar","CaretUpIcon","CaretDownIcon","wasOpen","createPortal","overlayIdentity","CheckIcon","CaretRightIcon"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { jsx as i } from "react/jsx-runtime";
2
+ import p from "../../assets/icons/building.svg.js";
3
+ const c = ({ size: o = 16, className: t = "", style: n = {}, onClick: r }) => {
4
+ const l = {
5
+ width: typeof o == "number" ? `${o}px` : o,
6
+ height: typeof o == "number" ? `${o}px` : o,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...n
10
+ };
11
+ return /* @__PURE__ */ i(p, { className: t, style: l, onClick: r });
12
+ };
13
+ export {
14
+ c as default
15
+ };
16
+ //# sourceMappingURL=BuildingIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildingIcon.js","sources":["../../../src/components/CustomIcons/BuildingIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport BuildingIconSvg from '../../assets/icons/building.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst BuildingIcon: React.FC<IconProps> = ({ size = 16, className = '', style = {}, onClick }) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <BuildingIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default BuildingIcon;\n"],"names":["BuildingIcon","size","className","style","onClick","iconStyle","jsx","BuildingIconSvg"],"mappings":";;AAUA,MAAMA,IAAoC,CAAC,EAAE,MAAAC,IAAO,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,IAAI,SAAAC,QAAc;AAC9F,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAgB,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AACtF;"}
@@ -0,0 +1,16 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import l from "../../assets/icons/chevrons_up_down.svg.js";
3
+ const m = ({ size: o = 16, className: n = "", style: r = {}, onClick: t }) => {
4
+ const p = {
5
+ width: typeof o == "number" ? `${o}px` : o,
6
+ height: typeof o == "number" ? `${o}px` : o,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...r
10
+ };
11
+ return /* @__PURE__ */ e(l, { className: n, style: p, onClick: t });
12
+ };
13
+ export {
14
+ m as default
15
+ };
16
+ //# sourceMappingURL=ChevronsUpDownIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChevronsUpDownIcon.js","sources":["../../../src/components/CustomIcons/ChevronsUpDownIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport ChevronsUpDownIconSvg from '../../assets/icons/chevrons_up_down.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst ChevronsUpDownIcon: React.FC<IconProps> = ({ size = 16, className = '', style = {}, onClick }) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <ChevronsUpDownIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default ChevronsUpDownIcon;\n"],"names":["ChevronsUpDownIcon","size","className","style","onClick","iconStyle","jsx","ChevronsUpDownIconSvg"],"mappings":";;AAUA,MAAMA,IAA0C,CAAC,EAAE,MAAAC,IAAO,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,IAAI,SAAAC,QAAc;AACpG,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAsB,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AAC5F;"}
@@ -0,0 +1,16 @@
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import c from "../../assets/icons/connector.svg.js";
3
+ const m = ({ size: o = 16, className: t = "", style: n = {}, onClick: r }) => {
4
+ const e = {
5
+ width: typeof o == "number" ? `${o}px` : o,
6
+ height: typeof o == "number" ? `${o}px` : o,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...n
10
+ };
11
+ return /* @__PURE__ */ l(c, { className: t, style: e, onClick: r });
12
+ };
13
+ export {
14
+ m as default
15
+ };
16
+ //# sourceMappingURL=ConnectorIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectorIcon.js","sources":["../../../src/components/CustomIcons/ConnectorIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport ConnectorIconSvg from '../../assets/icons/connector.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst ConnectorIcon: React.FC<IconProps> = ({ size = 16, className = '', style = {}, onClick }) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <ConnectorIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default ConnectorIcon;\n"],"names":["ConnectorIcon","size","className","style","onClick","iconStyle","jsx","ConnectorIconSvg"],"mappings":";;AAUA,MAAMA,IAAqC,CAAC,EAAE,MAAAC,IAAO,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,IAAI,SAAAC,QAAc;AAC/F,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAiB,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AACvF;"}
@@ -0,0 +1,16 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import p from "../../assets/icons/external_link.svg.js";
3
+ const i = ({ size: t = 16, className: n = "", style: o = {}, onClick: r }) => {
4
+ const l = {
5
+ width: typeof t == "number" ? `${t}px` : t,
6
+ height: typeof t == "number" ? `${t}px` : t,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...o
10
+ };
11
+ return /* @__PURE__ */ e(p, { className: n, style: l, onClick: r });
12
+ };
13
+ export {
14
+ i as default
15
+ };
16
+ //# sourceMappingURL=ExternalLinkIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExternalLinkIcon.js","sources":["../../../src/components/CustomIcons/ExternalLinkIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport ExternalLinkIconSvg from '../../assets/icons/external_link.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst ExternalLinkIcon: React.FC<IconProps> = ({ size = 16, className = '', style = {}, onClick }) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <ExternalLinkIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default ExternalLinkIcon;\n"],"names":["ExternalLinkIcon","size","className","style","onClick","iconStyle","jsx","ExternalLinkIconSvg"],"mappings":";;AAUA,MAAMA,IAAwC,CAAC,EAAE,MAAAC,IAAO,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,IAAI,SAAAC,QAAc;AAClG,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAoB,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AAC1F;"}
@@ -0,0 +1,16 @@
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import p from "../../assets/icons/field_coverage.svg.js";
3
+ const i = ({ size: o = 16, className: r = "", style: t = {}, onClick: e }) => {
4
+ const l = {
5
+ width: typeof o == "number" ? `${o}px` : o,
6
+ height: typeof o == "number" ? `${o}px` : o,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...t
10
+ };
11
+ return /* @__PURE__ */ n(p, { className: r, style: l, onClick: e });
12
+ };
13
+ export {
14
+ i as default
15
+ };
16
+ //# sourceMappingURL=FieldCoverageIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldCoverageIcon.js","sources":["../../../src/components/CustomIcons/FieldCoverageIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport FieldCoverageIconSvg from '../../assets/icons/field_coverage.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst FieldCoverageIcon: React.FC<IconProps> = ({ size = 16, className = '', style = {}, onClick }) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <FieldCoverageIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default FieldCoverageIcon;\n"],"names":["FieldCoverageIcon","size","className","style","onClick","iconStyle","jsx","FieldCoverageIconSvg"],"mappings":";;AAUA,MAAMA,IAAyC,CAAC,EAAE,MAAAC,IAAO,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,IAAI,SAAAC,QAAc;AACnG,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAqB,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AAC3F;"}
@@ -0,0 +1,16 @@
1
+ import { jsx as p } from "react/jsx-runtime";
2
+ import e from "../../assets/icons/layout.svg.js";
3
+ const c = ({ size: o = 16, className: t = "", style: r = {}, onClick: n }) => {
4
+ const l = {
5
+ width: typeof o == "number" ? `${o}px` : o,
6
+ height: typeof o == "number" ? `${o}px` : o,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...r
10
+ };
11
+ return /* @__PURE__ */ p(e, { className: t, style: l, onClick: n });
12
+ };
13
+ export {
14
+ c as default
15
+ };
16
+ //# sourceMappingURL=LayoutIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutIcon.js","sources":["../../../src/components/CustomIcons/LayoutIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport LayoutIconSvg from '../../assets/icons/layout.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst LayoutIcon: React.FC<IconProps> = ({ size = 16, className = '', style = {}, onClick }) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <LayoutIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default LayoutIcon;\n"],"names":["LayoutIcon","size","className","style","onClick","iconStyle","jsx","LayoutIconSvg"],"mappings":";;AAUA,MAAMA,IAAkC,CAAC,EAAE,MAAAC,IAAO,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,IAAI,SAAAC,QAAc;AAC5F,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAc,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AACpF;"}
@@ -0,0 +1,16 @@
1
+ import { jsx as p } from "react/jsx-runtime";
2
+ import e from "../../assets/icons/link.svg.js";
3
+ const i = ({ size: o = 16, className: t = "", style: n = {}, onClick: r }) => {
4
+ const l = {
5
+ width: typeof o == "number" ? `${o}px` : o,
6
+ height: typeof o == "number" ? `${o}px` : o,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...n
10
+ };
11
+ return /* @__PURE__ */ p(e, { className: t, style: l, onClick: r });
12
+ };
13
+ export {
14
+ i as default
15
+ };
16
+ //# sourceMappingURL=LinkIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkIcon.js","sources":["../../../src/components/CustomIcons/LinkIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport LinkIconSvg from '../../assets/icons/link.svg?react';\n\nexport interface IconProps {\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nconst LinkIcon: React.FC<IconProps> = ({ size = 16, className = '', style = {}, onClick }) => {\n const iconStyle: CSSProperties = {\n width: typeof size === 'number' ? `${size}px` : size,\n height: typeof size === 'number' ? `${size}px` : size,\n display: 'inline-block',\n fill: 'currentColor',\n ...style,\n };\n\n return <LinkIconSvg className={className} style={iconStyle} onClick={onClick} />;\n};\n\nexport default LinkIcon;\n"],"names":["LinkIcon","size","className","style","onClick","iconStyle","jsx","LinkIconSvg"],"mappings":";;AAUA,MAAMA,IAAgC,CAAC,EAAE,MAAAC,IAAO,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,IAAI,SAAAC,QAAc;AAC1F,QAAMC,IAA2B;AAAA,IAC7B,OAAO,OAAOJ,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IAChD,QAAQ,OAAOA,KAAS,WAAW,GAAGA,CAAI,OAAOA;AAAA,IACjD,SAAS;AAAA,IACT,MAAM;AAAA,IACN,GAAGE;AAAA,EAAA;AAGP,SAAO,gBAAAG,EAACC,GAAA,EAAY,WAAAL,GAAsB,OAAOG,GAAW,SAAAD,GAAkB;AAClF;"}
@@ -0,0 +1,16 @@
1
+ import { jsx as p } from "react/jsx-runtime";
2
+ import e from "../../assets/icons/playground.svg.js";
3
+ const c = ({ size: o = 16, className: r = "", style: t = {}, onClick: n }) => {
4
+ const l = {
5
+ width: typeof o == "number" ? `${o}px` : o,
6
+ height: typeof o == "number" ? `${o}px` : o,
7
+ display: "inline-block",
8
+ fill: "currentColor",
9
+ ...t
10
+ };
11
+ return /* @__PURE__ */ p(e, { className: r, style: l, onClick: n });
12
+ };
13
+ export {
14
+ c as default
15
+ };
16
+ //# sourceMappingURL=PlaygroundIcon.js.map