feat: new workspace screen with sticky search combobox design

- Replace workspace setup dialog with full-screen new workspace route
- Restyle Combobox SearchInput to match CombinedModelSelector Level 2 design:
  borderless sticky search bar above scroll area instead of inline bordered box
- CombinedModelSelector now uses shared SearchInput, removing duplicate ProviderSearchInput
- Fix TooltipTrigger children type to accept render functions (remove PropsWithChildren wrapper)
- Fix empty rightControls View causing gap between dictation and send buttons
- Add branch picker with searchable Combobox and GitBranch icons
- Muted icon buttons (attachment, dictation, voice mode) that brighten on hover
This commit is contained in:
Mohamed Boudra
2026-04-06 08:31:28 +07:00
parent c6e87744f1
commit 6362d429c7
10 changed files with 526 additions and 168 deletions
+9 -18
View File
@@ -659,13 +659,7 @@ export function Combobox({
</>
);
const defaultContent = (
<>
{effectiveOptionsPosition === "above-search" ? optionsList : null}
{searchable ? searchInput : null}
{effectiveOptionsPosition === "below-search" ? optionsList : null}
</>
);
const defaultContent = optionsList;
const content = children ?? defaultContent;
@@ -690,6 +684,7 @@ export function Combobox({
<Text style={styles.comboboxTitle}>{title}</Text>
</View>
{stickyHeader}
{!children && searchable ? searchInput : null}
<BottomSheetScrollView
contentContainerStyle={styles.comboboxScrollContent}
keyboardShouldPersistTaps="handled"
@@ -745,6 +740,7 @@ export function Combobox({
</>
) : (
<>
{searchable ? searchInput : null}
{effectiveOptionsPosition === "above-search" ? (
<ScrollView
ref={desktopOptionsScrollRef}
@@ -759,9 +755,7 @@ export function Combobox({
>
{optionsList}
</ScrollView>
) : null}
{searchable ? searchInput : null}
{effectiveOptionsPosition === "below-search" ? (
) : (
<ScrollView
contentContainerStyle={styles.desktopScrollContent}
keyboardShouldPersistTaps="handled"
@@ -770,7 +764,7 @@ export function Combobox({
>
{optionsList}
</ScrollView>
) : null}
)}
</>
)}
</Animated.View>
@@ -783,15 +777,12 @@ const styles = StyleSheet.create((theme) => ({
searchInputContainer: {
flexDirection: "row",
alignItems: "center",
borderWidth: 1,
borderColor: theme.colors.border,
backgroundColor: theme.colors.surface1,
borderRadius: theme.borderRadius.lg,
paddingHorizontal: theme.spacing[3],
marginHorizontal: theme.spacing[2],
marginBottom: theme.spacing[2],
marginTop: theme.spacing[1],
gap: theme.spacing[2],
backgroundColor: theme.colors.surface1,
borderBottomWidth: 1,
borderBottomColor: theme.colors.border,
...(IS_WEB ? {} : { marginHorizontal: theme.spacing[1] }),
},
searchInput: {
flex: 1,
+2 -3
View File
@@ -246,12 +246,11 @@ export function TooltipTrigger({
asChild = false,
triggerRefProp = "ref",
...props
}: PropsWithChildren<
PressableProps & {
}: PressableProps & {
asChild?: boolean;
triggerRefProp?: string;
}
>): ReactElement {
): ReactElement {
const ctx = useTooltipContext("TooltipTrigger");
const openTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);