| ... | @@ -53,7 +53,6 @@ import { folderDropTarget, resolveDroppedFolderPath } from "./folderDrop"; | ... | @@ -53,7 +53,6 @@ import { folderDropTarget, resolveDroppedFolderPath } from "./folderDrop"; |
| 53 | import { createModelSelection, normalizeModelSlug } from "@t3tools/shared/model"; | 53 | import { createModelSelection, normalizeModelSlug } from "@t3tools/shared/model"; |
| 54 | import { USAGE_LIMITS_COMMAND } from "@t3tools/shared/usageLimits"; | 54 | import { USAGE_LIMITS_COMMAND } from "@t3tools/shared/usageLimits"; |
| 55 | import { | 55 | import { |
| 56 | Fragment, | | |
| 57 | memo, | 56 | memo, |
| 58 | type ComponentProps, | 57 | type ComponentProps, |
| 59 | type ReactNode, | 58 | type ReactNode, |
| ... | @@ -187,8 +186,6 @@ import { | ... | @@ -187,8 +186,6 @@ import { |
| 187 | import { useComposerPathSearch } from "../../lib/composerPathSearchState"; | 186 | import { useComposerPathSearch } from "../../lib/composerPathSearchState"; |
| 188 | import { replaceComposerContextReferences } from "@t3tools/shared/composerContextReferences"; | 187 | import { replaceComposerContextReferences } from "@t3tools/shared/composerContextReferences"; |
| 189 | import { | 188 | import { |
| 190 | COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX, | | |
| 191 | COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX, | | |
| 192 | getRestingComposerImagePreviewCounts, | 189 | getRestingComposerImagePreviewCounts, |
| 193 | resolveRestingComposerControlsLayout, | 190 | resolveRestingComposerControlsLayout, |
| 194 | shouldAnimateComposerRestingTransition, | 191 | shouldAnimateComposerRestingTransition, |
| ... | @@ -197,7 +194,6 @@ import { | ... | @@ -197,7 +194,6 @@ import { |
| 197 | shouldUseRestingComposerLayout, | 194 | shouldUseRestingComposerLayout, |
| 198 | } from "../composerFooterLayout"; | 195 | } from "../composerFooterLayout"; |
| 199 | import { measureRestingComposerControls } from "./restingComposerControlsMeasurement"; | 196 | import { measureRestingComposerControls } from "./restingComposerControlsMeasurement"; |
| 200 | import { observeResponsiveBreakpointFade, usePanelAnimationSettings } from "../../panelAnimations"; | | |
| 201 | import { type ComposerPromptEditorHandle, ComposerPromptEditor } from "../ComposerPromptEditor"; | 197 | import { type ComposerPromptEditorHandle, ComposerPromptEditor } from "../ComposerPromptEditor"; |
| 202 | import { | 198 | import { |
| 203 | ComposerContextActionsContext, | 199 | ComposerContextActionsContext, |
| ... | @@ -994,22 +990,32 @@ const extendReplacementRangeForTrailingSpace = ( | ... | @@ -994,22 +990,32 @@ const extendReplacementRangeForTrailingSpace = ( |
| 994 | return text[rangeEnd] === " " ? rangeEnd + 1 : rangeEnd; | 990 | return text[rangeEnd] === " " ? rangeEnd + 1 : rangeEnd; |
| 995 | }; | 991 | }; |
| 996 | | 992 | |
| 997 | function useRestingComposerControlsLayout(host: HTMLDivElement | null) { | 993 | function useRestingComposerControlsLayout(host: HTMLDivElement | null, useControlsAsHost = false) { |
| | 994 | const [controls, setControls] = useState<HTMLDivElement | null>(null); |
| 998 | const controlsRef = useRef<HTMLDivElement>(null); | 995 | const controlsRef = useRef<HTMLDivElement>(null); |
| | 996 | const attachControls = useCallback((element: HTMLDivElement | null) => { |
| | 997 | controlsRef.current = element; |
| | 998 | setControls(element); |
| | 999 | }, []); |
| 999 | const hostRef = useRef(host); | 1000 | const hostRef = useRef(host); |
| 1000 | hostRef.current = host; | 1001 | hostRef.current = host; |
| 1001 | const [layout, setLayout] = useState({ hiddenCount: 0, visible: true }); | 1002 | const [layout, setLayout] = useState<{ |
| | 1003 | hiddenCount: number; |
| | 1004 | iconOnlyCount?: number; |
| | 1005 | visible: boolean; |
| | 1006 | }>({ hiddenCount: 0, visible: true }); |
| 1002 | | 1007 | |
| 1003 | const measure = useCallback(() => { | 1008 | const measure = useCallback(() => { |
| 1004 | const currentHost = hostRef.current; | 1009 | const currentHost = useControlsAsHost ? controls : hostRef.current; |
| 1005 | const controls = controlsRef.current; | | |
| 1006 | // The controls only mount while the composer rests, so the expanded | | |
| 1007 | // composer pays no layout reads here despite the every-render effect. | | |
| 1008 | if (currentHost === null || !controls) return; | 1010 | if (currentHost === null || !controls) return; |
| 1009 | | 1011 | |
| 1010 | const measurement = measureRestingComposerControls(controls); | 1012 | const measurement = measureRestingComposerControls(controls); |
| 1011 | if (!measurement) return; | 1013 | if (!measurement) return; |
| 1012 | const hostWidth = currentHost.clientWidth; | 1014 | const style = getComputedStyle(currentHost); |
| | 1015 | const hostWidth = |
| | 1016 | currentHost.clientWidth - |
| | 1017 | (Number.parseFloat(style.paddingInlineStart) || 0) - |
| | 1018 | (Number.parseFloat(style.paddingInlineEnd) || 0); |
| 1013 | | 1019 | |
| 1014 | setLayout((current) => { | 1020 | setLayout((current) => { |
| 1015 | const next = resolveRestingComposerControlsLayout({ | 1021 | const next = resolveRestingComposerControlsLayout({ |
| ... | @@ -1017,25 +1023,48 @@ function useRestingComposerControlsLayout(host: HTMLDivElement | null) { | ... | @@ -1017,25 +1023,48 @@ function useRestingComposerControlsLayout(host: HTMLDivElement | null) { |
| 1017 | hostWidth, | 1023 | hostWidth, |
| 1018 | previous: current, | 1024 | previous: current, |
| 1019 | }); | 1025 | }); |
| 1020 | return next.hiddenCount === current.hiddenCount && next.visible === current.visible | 1026 | return next.hiddenCount === current.hiddenCount && |
| | 1027 | next.iconOnlyCount === current.iconOnlyCount && |
| | 1028 | next.visible === current.visible |
| 1021 | ? current | 1029 | ? current |
| 1022 | : next; | 1030 | : next; |
| 1023 | }); | 1031 | }); |
| 1024 | }, []); | 1032 | }, [controls, useControlsAsHost]); |
| 1025 | | 1033 | |
| 1026 | useLayoutEffect(measure); | 1034 | useLayoutEffect(measure, [measure, host]); |
| 1027 | useEffect(() => { | 1035 | useEffect(() => { |
| 1028 | if (!host) return; | 1036 | const currentHost = useControlsAsHost ? controls : host; |
| | 1037 | if (!currentHost || !controls) return; |
| 1029 | const observer = new ResizeObserver(measure); | 1038 | const observer = new ResizeObserver(measure); |
| 1030 | observer.observe(host); | 1039 | const observeControls = () => { |
| | 1040 | observer.disconnect(); |
| | 1041 | observer.observe(currentHost); |
| | 1042 | observer.observe(controls); |
| | 1043 | controls |
| | 1044 | .querySelectorAll<HTMLElement>( |
| | 1045 | "[data-resting-block], [data-composer-control-label], [data-chat-provider-model-picker-label]", |
| | 1046 | ) |
| | 1047 | .forEach((element) => observer.observe(element)); |
| | 1048 | measure(); |
| | 1049 | }; |
| | 1050 | observeControls(); |
| | 1051 | const mutations = new MutationObserver(observeControls); |
| | 1052 | mutations.observe(controls, { childList: true, subtree: true, characterData: true }); |
| 1031 | document.fonts.addEventListener("loadingdone", measure); | 1053 | document.fonts.addEventListener("loadingdone", measure); |
| 1032 | return () => { | 1054 | return () => { |
| 1033 | observer.disconnect(); | 1055 | observer.disconnect(); |
| | 1056 | mutations.disconnect(); |
| 1034 | document.fonts.removeEventListener("loadingdone", measure); | 1057 | document.fonts.removeEventListener("loadingdone", measure); |
| 1035 | }; | 1058 | }; |
| 1036 | }, [host, measure]); | 1059 | }, [host, controls, useControlsAsHost, measure]); |
| 1037 | | 1060 | |
| 1038 | return { controlsRef, hiddenBlockCount: layout.hiddenCount, controlsVisible: layout.visible }; | 1061 | return { |
| | 1062 | controlsRef, |
| | 1063 | attachControls, |
| | 1064 | hiddenBlockCount: layout.hiddenCount, |
| | 1065 | iconOnlyBlockCount: layout.iconOnlyCount ?? 0, |
| | 1066 | controlsVisible: layout.visible, |
| | 1067 | }; |
| 1039 | } | 1068 | } |
| 1040 | | 1069 | |
| 1041 | const ComposerFooterModeControls = memo(function ComposerFooterModeControls(props: { | 1070 | const ComposerFooterModeControls = memo(function ComposerFooterModeControls(props: { |
| ... | @@ -1092,7 +1121,7 @@ const ComposerFooterModeControls = memo(function ComposerFooterModeControls(prop | ... | @@ -1092,7 +1121,7 @@ const ComposerFooterModeControls = memo(function ComposerFooterModeControls(prop |
| 1092 | opticalSize={size === "xs" ? "default" : "large"} | 1121 | opticalSize={size === "xs" ? "default" : "large"} |
| 1093 | /> | 1122 | /> |
| 1094 | )} | 1123 | )} |
| 1095 | <span className="sr-only sm:not-sr-only"> | 1124 | <span data-composer-control-label className="sr-only sm:not-sr-only"> |
| 1096 | {props.interactionMode === "plan" ? "Plan" : "Build"} | 1125 | {props.interactionMode === "plan" ? "Plan" : "Build"} |
| 1097 | </span> | 1126 | </span> |
| 1098 | </TooltipTrigger> | 1127 | </TooltipTrigger> |
| ... | @@ -1123,7 +1152,7 @@ const ComposerFooterModeControls = memo(function ComposerFooterModeControls(prop | ... | @@ -1123,7 +1152,7 @@ const ComposerFooterModeControls = memo(function ComposerFooterModeControls(prop |
| 1123 | } | 1152 | } |
| 1124 | > | 1153 | > |
| 1125 | <ComposerControlIcon icon={RuntimeModeIcon} size={size} /> | 1154 | <ComposerControlIcon icon={RuntimeModeIcon} size={size} /> |
| 1126 | <SelectValue>{runtimeModeOption.label}</SelectValue> | 1155 | <SelectValue data-composer-control-label>{runtimeModeOption.label}</SelectValue> |
| 1127 | </TooltipTrigger> | 1156 | </TooltipTrigger> |
| 1128 | <SelectPopup alignItemWithTrigger={false} {...composerFloatingLayerProps}> | 1157 | <SelectPopup alignItemWithTrigger={false} {...composerFloatingLayerProps}> |
| 1129 | {runtimeModeOptions.map((mode) => { | 1158 | {runtimeModeOptions.map((mode) => { |
| ... | @@ -2104,8 +2133,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -2104,8 +2133,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 2104 | key: 0, | 2133 | key: 0, |
| 2105 | active: false, | 2134 | active: false, |
| 2106 | }); | 2135 | }); |
| 2107 | const { active: panelAnimationsActive, durationMs: panelAnimationDurationMs } = | | |
| 2108 | usePanelAnimationSettings(); | | |
| 2109 | const isComposerCollapsedMobile = | 2136 | const isComposerCollapsedMobile = |
| 2110 | isMobileViewport && !forceExpandedOnMobile && !isComposerFocused && !hasMultilinePrompt; | 2137 | isMobileViewport && !forceExpandedOnMobile && !isComposerFocused && !hasMultilinePrompt; |
| 2111 | | 2138 | |
| ... | @@ -2120,7 +2147,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -2120,7 +2147,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 2120 | }); | 2147 | }); |
| 2121 | const attachmentInputRef = useRef<HTMLInputElement>(null); | 2148 | const attachmentInputRef = useRef<HTMLInputElement>(null); |
| 2122 | const composerFormRef = useRef<HTMLFormElement>(null); | 2149 | const composerFormRef = useRef<HTMLFormElement>(null); |
| 2123 | const composerFooterControlsRef = useRef<HTMLDivElement>(null); | | |
| 2124 | const composerSurfaceRef = useRef<HTMLDivElement>(null); | 2150 | const composerSurfaceRef = useRef<HTMLDivElement>(null); |
| 2125 | const providerInputRejectedRef = useRef(false); | 2151 | const providerInputRejectedRef = useRef(false); |
| 2126 | const composerSelectLockRef = useRef(false); | 2152 | const composerSelectLockRef = useRef(false); |
| ... | @@ -2628,9 +2654,12 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -2628,9 +2654,12 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 2628 | const providerTraitsPicker = renderProviderTraitsPicker(providerTraitsPickerInput); | 2654 | const providerTraitsPicker = renderProviderTraitsPicker(providerTraitsPickerInput); |
| 2629 | const { | 2655 | const { |
| 2630 | controlsRef: restingComposerControlsRef, | 2656 | controlsRef: restingComposerControlsRef, |
| | 2657 | attachControls: attachRestingComposerControls, |
| 2631 | hiddenBlockCount: restingControlsHiddenBlockCount, | 2658 | hiddenBlockCount: restingControlsHiddenBlockCount, |
| | 2659 | iconOnlyBlockCount: restingControlsIconOnlyBlockCount, |
| 2632 | controlsVisible: restingControlsVisible, | 2660 | controlsVisible: restingControlsVisible, |
| 2633 | } = useRestingComposerControlsLayout(restingControlsHost); | 2661 | } = useRestingComposerControlsLayout(restingControlsHost); |
| | 2662 | const expandedControlsLayout = useRestingComposerControlsLayout(null, true); |
| 2634 | const pendingPrimaryAction = useMemo( | 2663 | const pendingPrimaryAction = useMemo( |
| 2635 | () => | 2664 | () => |
| 2636 | activePendingProgress | 2665 | activePendingProgress |
| ... | @@ -3177,22 +3206,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -3177,22 +3206,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 3177 | setIsComposerPrimaryActionsCompact(initialCompactness.primaryActionsCompact); | 3206 | setIsComposerPrimaryActionsCompact(initialCompactness.primaryActionsCompact); |
| 3178 | setIsComposerFooterCompact(initialCompactness.footerCompact); | 3207 | setIsComposerFooterCompact(initialCompactness.footerCompact); |
| 3179 | if (typeof ResizeObserver === "undefined") return; | 3208 | if (typeof ResizeObserver === "undefined") return; |
| 3180 | const footerControls = composerFooterControlsRef.current; | | |
| 3181 | const stopFooterControlsFade = footerControls | | |
| 3182 | ? observeResponsiveBreakpointFade({ | | |
| 3183 | target: footerControls, | | |
| 3184 | container: composerForm, | | |
| 3185 | active: panelAnimationsActive, | | |
| 3186 | durationMs: panelAnimationDurationMs, | | |
| 3187 | breakpoint: { | | |
| 3188 | value: composerFooterHasWideActions | | |
| 3189 | ? COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX | | |
| 3190 | : COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX, | | |
| 3191 | unit: "px", | | |
| 3192 | }, | | |
| 3193 | }) | | |
| 3194 | : undefined; | | |
| 3195 | | | |
| 3196 | const observer = new ResizeObserver(() => { | 3209 | const observer = new ResizeObserver(() => { |
| 3197 | const nextCompactness = measureFooterCompactness(); | 3210 | const nextCompactness = measureFooterCompactness(); |
| 3198 | setIsComposerPrimaryActionsCompact((previous) => | 3211 | setIsComposerPrimaryActionsCompact((previous) => |
| ... | @@ -3208,7 +3221,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -3208,7 +3221,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 3208 | observer.observe(composerForm); | 3221 | observer.observe(composerForm); |
| 3209 | return () => { | 3222 | return () => { |
| 3210 | observer.disconnect(); | 3223 | observer.disconnect(); |
| 3211 | stopFooterControlsFade?.(); | | |
| 3212 | }; | 3224 | }; |
| 3213 | }, [ | 3225 | }, [ |
| 3214 | activeThreadId, | 3226 | activeThreadId, |
| ... | @@ -3216,8 +3228,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -3216,8 +3228,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 3216 | composerFooterHasWideActions, | 3228 | composerFooterHasWideActions, |
| 3217 | isComposerApprovalState, | 3229 | isComposerApprovalState, |
| 3218 | isComposerCollapsedMobile, | 3230 | isComposerCollapsedMobile, |
| 3219 | panelAnimationDurationMs, | | |
| 3220 | panelAnimationsActive, | | |
| 3221 | ]); | 3231 | ]); |
| 3222 | | 3232 | |
| 3223 | // ------------------------------------------------------------------ | 3233 | // ------------------------------------------------------------------ |
| ... | @@ -4926,11 +4936,15 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -4926,11 +4936,15 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 4926 | setIsComposerScrollCollapsed, | 4936 | setIsComposerScrollCollapsed, |
| 4927 | ]); | 4937 | ]); |
| 4928 | | 4938 | |
| 4929 | const restingHiddenBlockCount = composerControlsInStrip ? restingControlsHiddenBlockCount : 0; | 4939 | const restingHiddenBlockCount = composerControlsInStrip |
| 4930 | const composerControlsCompact = !composerControlsInStrip && isComposerFooterCompact; | 4940 | ? restingControlsHiddenBlockCount |
| | 4941 | : expandedControlsLayout.hiddenBlockCount; |
| | 4942 | const iconOnlyBlockCount = composerControlsInStrip |
| | 4943 | ? restingControlsIconOnlyBlockCount |
| | 4944 | : expandedControlsLayout.iconOnlyBlockCount; |
| 4931 | const restingProviderTraitsPicker = renderProviderTraitsPicker({ | 4945 | const restingProviderTraitsPicker = renderProviderTraitsPicker({ |
| 4932 | ...providerTraitsPickerInput, | 4946 | ...providerTraitsPickerInput, |
| 4933 | size: "xs", | 4947 | size: composerControlsInStrip ? "xs" : "sm", |
| 4934 | hidden: composerControlsHidden || restingHiddenBlockCount > 1, | 4948 | hidden: composerControlsHidden || restingHiddenBlockCount > 1, |
| 4935 | }); | 4949 | }); |
| 4936 | const restingBlockDefs = [ | 4950 | const restingBlockDefs = [ |
| ... | @@ -4941,7 +4955,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -4941,7 +4955,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 4941 | content: ( | 4955 | content: ( |
| 4942 | <> | 4956 | <> |
| 4943 | <ComposerControlSeparator size={composerControlsInStrip ? "xs" : "sm"} /> | 4957 | <ComposerControlSeparator size={composerControlsInStrip ? "xs" : "sm"} /> |
| 4944 | {composerControlsInStrip ? restingProviderTraitsPicker : providerTraitsPicker} | 4958 | {restingProviderTraitsPicker} |
| 4945 | </> | 4959 | </> |
| 4946 | ), | 4960 | ), |
| 4947 | }, | 4961 | }, |
| ... | @@ -5048,7 +5062,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -5048,7 +5062,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 5048 | triggerClassName={ | 5062 | triggerClassName={ |
| 5049 | composerControlsInStrip | 5063 | composerControlsInStrip |
| 5050 | ? "min-w-13 shrink text-xs! @max-[640px]/composer-surface:[&_[data-chat-provider-model-picker-label]]:w-0 @max-[640px]/composer-surface:[&_[data-chat-provider-model-picker-label]]:flex-none" | 5064 | ? "min-w-13 shrink text-xs! @max-[640px]/composer-surface:[&_[data-chat-provider-model-picker-label]]:w-0 @max-[640px]/composer-surface:[&_[data-chat-provider-model-picker-label]]:flex-none" |
| 5051 | : "-ms-2.5" | 5065 | : "-ms-2.5 min-w-13" |
| 5052 | } | 5066 | } |
| 5053 | terminalOpen={terminalOpen} | 5067 | terminalOpen={terminalOpen} |
| 5054 | open={isComposerModelPickerOpen} | 5068 | open={isComposerModelPickerOpen} |
| ... | @@ -5075,65 +5089,52 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -5075,65 +5089,52 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 5075 | onOpenProviderSetup={onOpenProviderSetup} | 5089 | onOpenProviderSetup={onOpenProviderSetup} |
| 5076 | /> | 5090 | /> |
| 5077 | | 5091 | |
| 5078 | {composerControlsCompact ? ( | 5092 | <> |
| 5079 | <CompactComposerControlsMenu | 5093 | {restingBlockDefs.map((def, index) => { |
| 5080 | interactionMode={interactionMode} | 5094 | const hidden = index >= restingBlockDefs.length - restingHiddenBlockCount; |
| 5081 | runtimeMode={runtimeMode} | 5095 | return ( |
| 5082 | showInteractionModeToggle={planModeUiEnabled} | | |
| 5083 | traitsMenuContent={providerTraitsMenuContent} | | |
| 5084 | onToggleInteractionMode={toggleInteractionMode} | | |
| 5085 | onRuntimeModeChange={handleRuntimeModeChange} | | |
| 5086 | /> | | |
| 5087 | ) : ( | | |
| 5088 | <> | | |
| 5089 | {restingBlockDefs.map((def, index) => { | | |
| 5090 | if (!composerControlsInStrip) { | | |
| 5091 | return <Fragment key={def.id}>{def.content}</Fragment>; | | |
| 5092 | } | | |
| 5093 | const hidden = index >= restingBlockDefs.length - restingHiddenBlockCount; | | |
| 5094 | return ( | | |
| 5095 | <div | | |
| 5096 | key={def.id} | | |
| 5097 | data-resting-block={def.id} | | |
| 5098 | aria-hidden={hidden || undefined} | | |
| 5099 | inert={hidden || undefined} | | |
| 5100 | className={cn( | | |
| 5101 | "flex w-max min-w-max shrink-0 items-center gap-1", | | |
| 5102 | hidden && "pointer-events-none invisible absolute", | | |
| 5103 | )} | | |
| 5104 | > | | |
| 5105 | {def.content} | | |
| 5106 | </div> | | |
| 5107 | ); | | |
| 5108 | })} | | |
| 5109 | {composerControlsInStrip ? ( | | |
| 5110 | <div | 5096 | <div |
| 5111 | data-resting-controls-overflow | 5097 | key={def.id} |
| 5112 | aria-hidden={hiddenRestingBlockIds.length === 0 || undefined} | 5098 | data-resting-block={def.id} |
| 5113 | inert={hiddenRestingBlockIds.length === 0 || undefined} | 5099 | data-composer-block-icon-only={ |
| | 5100 | index >= restingBlockDefs.length - iconOnlyBlockCount ? "true" : "false" |
| | 5101 | } |
| | 5102 | aria-hidden={hidden || undefined} |
| | 5103 | inert={hidden || undefined} |
| 5114 | className={cn( | 5104 | className={cn( |
| 5115 | "min-w-0 shrink-0", | 5105 | "flex w-max min-w-max shrink-0 items-center gap-1", |
| 5116 | hiddenRestingBlockIds.length === 0 && "pointer-events-none invisible absolute", | 5106 | hidden && "pointer-events-none invisible absolute", |
| | 5107 | index >= restingBlockDefs.length - iconOnlyBlockCount && |
| | 5108 | "[&_[data-composer-control-label]]:pointer-events-none [&_[data-composer-control-label]]:invisible [&_[data-composer-control-label]]:absolute [&_[data-composer-control-label]]:w-max [&_[data-composer-control-label]]:max-w-none [&_[data-composer-control-compact-icon]]:[visibility:inherit] [&_[data-composer-control-compact-icon]]:relative", |
| 5117 | )} | 5109 | )} |
| 5118 | > | 5110 | > |
| 5119 | <CompactComposerControlsMenu | 5111 | {def.content} |
| 5120 | interactionMode={interactionMode} | | |
| 5121 | runtimeMode={runtimeMode} | | |
| 5122 | size="xs" | | |
| 5123 | hidden={composerControlsHidden || hiddenRestingBlockIds.length === 0} | | |
| 5124 | showInteractionModeToggle={ | | |
| 5125 | planModeUiEnabled && hiddenRestingBlockIds.includes("mode") | | |
| 5126 | } | | |
| 5127 | traitsMenuContent={ | | |
| 5128 | hiddenRestingBlockIds.includes("traits") ? providerTraitsMenuContent : undefined | | |
| 5129 | } | | |
| 5130 | onToggleInteractionMode={toggleInteractionMode} | | |
| 5131 | onRuntimeModeChange={handleRuntimeModeChange} | | |
| 5132 | /> | | |
| 5133 | </div> | 5112 | </div> |
| 5134 | ) : null} | 5113 | ); |
| 5135 | </> | 5114 | })} |
| 5136 | )} | 5115 | <div |
| | 5116 | data-resting-controls-overflow |
| | 5117 | aria-hidden={hiddenRestingBlockIds.length === 0 || undefined} |
| | 5118 | inert={hiddenRestingBlockIds.length === 0 || undefined} |
| | 5119 | className={cn( |
| | 5120 | "min-w-0 shrink-0", |
| | 5121 | hiddenRestingBlockIds.length === 0 && "pointer-events-none invisible absolute", |
| | 5122 | )} |
| | 5123 | > |
| | 5124 | <CompactComposerControlsMenu |
| | 5125 | interactionMode={interactionMode} |
| | 5126 | runtimeMode={runtimeMode} |
| | 5127 | size={composerControlsInStrip ? "xs" : "sm"} |
| | 5128 | hidden={composerControlsHidden || hiddenRestingBlockIds.length === 0} |
| | 5129 | showInteractionModeToggle={planModeUiEnabled && hiddenRestingBlockIds.includes("mode")} |
| | 5130 | traitsMenuContent={ |
| | 5131 | hiddenRestingBlockIds.includes("traits") ? providerTraitsMenuContent : undefined |
| | 5132 | } |
| | 5133 | onToggleInteractionMode={toggleInteractionMode} |
| | 5134 | onRuntimeModeChange={handleRuntimeModeChange} |
| | 5135 | /> |
| | 5136 | </div> |
| | 5137 | </> |
| 5137 | </> | 5138 | </> |
| 5138 | ); | 5139 | ); |
| 5139 | const showTasksTab = | 5140 | const showTasksTab = |
| ... | @@ -6159,7 +6160,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -6159,7 +6160,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6159 | {composerControlsInStrip && restingControlsHost | 6160 | {composerControlsInStrip && restingControlsHost |
| 6160 | ? createPortal( | 6161 | ? createPortal( |
| 6161 | <div | 6162 | <div |
| 6162 | ref={restingComposerControlsRef} | 6163 | ref={attachRestingComposerControls} |
| 6163 | data-chat-composer-resting-controls="true" | 6164 | data-chat-composer-resting-controls="true" |
| 6164 | aria-hidden={restingControlsVisible ? undefined : true} | 6165 | aria-hidden={restingControlsVisible ? undefined : true} |
| 6165 | inert={restingControlsVisible ? undefined : true} | 6166 | inert={restingControlsVisible ? undefined : true} |
| ... | @@ -6961,11 +6962,11 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) | ... | @@ -6961,11 +6962,11 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 6961 | )} | 6962 | )} |
| 6962 | > | 6963 | > |
| 6963 | <div | 6964 | <div |
| 6964 | ref={composerFooterControlsRef} | 6965 | ref={expandedControlsLayout.attachControls} |
| 6965 | data-chat-composer-controls="left" | 6966 | data-chat-composer-controls="left" |
| 6966 | data-chat-composer-footer-controls="true" | 6967 | data-chat-composer-footer-controls="true" |
| 6967 | className={cn( | 6968 | className={cn( |
| 6968 | "-m-1 -ms-3.5 flex min-w-0 flex-1 items-center gap-1 overflow-x-auto p-1 ps-3.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", | 6969 | "relative -m-1 -ms-3.5 flex min-w-0 flex-1 items-center gap-1 overflow-x-auto p-1 ps-3.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", |
| 6969 | isComposerResting && "hidden", | 6970 | isComposerResting && "hidden", |
| 6970 | )} | 6971 | )} |
| 6971 | > | 6972 | > |