Skip to content

Commit edf1116

Browse files
committed
Implement dynamic width adjustment for the dropdown button
1 parent 76e4fd4 commit edf1116

3 files changed

Lines changed: 171 additions & 171 deletions

File tree

packages/ui/src/components/editor/Dropdown/Dropdown.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
cursor: pointer;
1414
background-color: var(--vscode-dropdown-background);
1515
color: var(--vscode-dropdown-foreground);
16+
width: 100%;
1617

1718
&--open {
1819
border-color: var(--vscode-focusBorder);

packages/vscode/src/view/frontend/home/HomeView/HomeView.module.scss

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
justify-content: space-between;
131131
align-items: center;
132132
padding: 0 var(--padding-12px);
133+
gap: var(--padding-8px);
133134

134135
&__left {
135136
display: flex;
@@ -139,10 +140,6 @@
139140

140141
&__right {
141142
flex: 1;
142-
display: flex;
143-
justify-content: flex-end;
144-
align-items: center;
145-
gap: var(--padding-6px);
146143
}
147144
}
148145

packages/vscode/src/view/frontend/home/HomeView/HomeView.tsx

Lines changed: 169 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ const api_mode_labels: Record<ApiMode, string> = {
7070

7171
export const HomeView: React.FC<Props> = (props) => {
7272
const [estimated_input_tokens, set_estimated_input_tokens] = useState(0)
73+
// We need this because we can't use overflow: hidden
74+
// due to absolutely positioned dropdown menu
7375
const [dropdown_max_width, set_dropdown_max_width] = useState<
7476
number | undefined
7577
>(undefined)
@@ -182,189 +184,189 @@ export const HomeView: React.FC<Props> = (props) => {
182184
<div ref={container_ref} className={styles.container}>
183185
<Scrollable>
184186
<div className={styles.inner}>
185-
<div className={styles.top}>
186-
<div className={styles.top__left}>
187-
<IconButton
188-
codicon_icon="chevron-left"
189-
on_click={props.on_show_intro}
190-
title="Return to intro screen"
187+
<div className={styles.top}>
188+
<div className={styles.top__left}>
189+
<IconButton
190+
codicon_icon="chevron-left"
191+
on_click={props.on_show_intro}
192+
title="Return to intro screen"
193+
/>
194+
<div ref={switch_container_ref}>
195+
<UiSwitch
196+
value={props.home_view_type}
197+
on_change={props.on_home_view_type_change}
198+
options={Object.values(HOME_VIEW_TYPES)}
191199
/>
192-
<div ref={switch_container_ref}>
193-
<UiSwitch
194-
value={props.home_view_type}
195-
on_change={props.on_home_view_type_change}
196-
options={Object.values(HOME_VIEW_TYPES)}
197-
/>
198-
</div>
199-
</div>
200-
201-
<div className={styles.top__right} ref={dropdown_container_ref}>
202-
{props.home_view_type == HOME_VIEW_TYPES.WEB && (
203-
<UiDropdown
204-
options={Object.entries(web_mode_labels).map(
205-
([value, label]) => ({ value: value as WebMode, label })
206-
)}
207-
selected_value={props.web_mode}
208-
on_change={props.on_web_mode_change}
209-
title={`Current mode: ${web_mode_labels[props.web_mode]}`}
210-
max_width={dropdown_max_width}
211-
/>
212-
)}
213-
{props.home_view_type == HOME_VIEW_TYPES.API && (
214-
<UiDropdown
215-
options={Object.entries(api_mode_labels).map(
216-
([value, label]) => ({ value: value as ApiMode, label })
217-
)}
218-
selected_value={props.api_mode}
219-
on_change={props.on_api_mode_change}
220-
title={`Current mode: ${api_mode_labels[props.api_mode]}`}
221-
max_width={dropdown_max_width}
222-
/>
223-
)}
224200
</div>
225201
</div>
226202

227-
<UiSeparator height={8} />
228-
229-
{!props.is_connected &&
230-
props.home_view_type == HOME_VIEW_TYPES.WEB && (
231-
<>
232-
<div className={styles['browser-extension-message']}>
233-
<span>
234-
Get the Connector browser extension for hands-free chat
235-
inititalizations
236-
</span>
237-
<a href="https://chromewebstore.google.com/detail/code-web-chat-connector/ljookipcanaglfaocjbgdicfbdhhjffp">
238-
Chrome Web Store ↗
239-
</a>
240-
<a href="https://addons.mozilla.org/en-US/firefox/addon/gemini-coder-connector/">
241-
Firefox Add-ons ↗
242-
</a>
243-
</div>
244-
245-
<UiSeparator height={8} />
246-
</>
203+
<div className={styles.top__right} ref={dropdown_container_ref}>
204+
{props.home_view_type == HOME_VIEW_TYPES.WEB && (
205+
<UiDropdown
206+
options={Object.entries(web_mode_labels).map(
207+
([value, label]) => ({ value: value as WebMode, label })
208+
)}
209+
selected_value={props.web_mode}
210+
on_change={props.on_web_mode_change}
211+
title={`Current mode: ${web_mode_labels[props.web_mode]}`}
212+
max_width={dropdown_max_width}
213+
/>
214+
)}
215+
{props.home_view_type == HOME_VIEW_TYPES.API && (
216+
<UiDropdown
217+
options={Object.entries(api_mode_labels).map(
218+
([value, label]) => ({ value: value as ApiMode, label })
219+
)}
220+
selected_value={props.api_mode}
221+
on_change={props.on_api_mode_change}
222+
title={`Current mode: ${api_mode_labels[props.api_mode]}`}
223+
max_width={dropdown_max_width}
224+
/>
247225
)}
248-
249-
<div className={styles['chat-input']}>
250-
<UiChatInput
251-
value={current_prompt}
252-
chat_history={props.chat_history}
253-
on_change={handle_input_change}
254-
on_submit={handle_submit}
255-
on_submit_with_control={handle_submit_with_control}
256-
on_copy={
257-
props.home_view_type == HOME_VIEW_TYPES.WEB &&
258-
props.web_mode != 'no-context'
259-
? handle_copy
260-
: undefined
261-
}
262-
on_search_click={props.on_search_click}
263-
on_at_sign_click={props.on_at_sign_click}
264-
is_web_mode={props.home_view_type == HOME_VIEW_TYPES.WEB}
265-
is_connected={props.is_connected}
266-
token_count={estimated_input_tokens}
267-
submit_disabled_title={
268-
!props.is_connected
269-
? 'WebSocket connection not established. Please install the browser extension.'
270-
: 'Type something'
271-
}
272-
is_in_code_completions_mode={is_in_code_completions_mode}
273-
has_active_selection={props.has_active_selection}
274-
has_active_editor={props.has_active_editor}
275-
on_caret_position_change={props.on_caret_position_change}
276-
translations={{
277-
type_something: 'Type something',
278-
completion_instructions: 'Completion instructions',
279-
send_request: 'Send request',
280-
initialize_chat: 'Initialize chat',
281-
select_preset: 'Select preset',
282-
select_config: 'Select config',
283-
code_completions_mode_unavailable_with_text_selection:
284-
'Unable to work with text selection',
285-
code_completions_mode_unavailable_without_active_editor:
286-
'This mode requires active editor',
287-
search: 'Search history'
288-
}}
289-
/>
290226
</div>
227+
</div>
228+
229+
<UiSeparator height={8} />
291230

292-
{((props.home_view_type == HOME_VIEW_TYPES.WEB &&
293-
props.web_mode == 'edit') ||
294-
(props.home_view_type == HOME_VIEW_TYPES.API &&
295-
props.api_mode == 'edit')) && (
231+
{!props.is_connected &&
232+
props.home_view_type == HOME_VIEW_TYPES.WEB && (
296233
<>
297-
<div className={styles['edit-format']}>
234+
<div className={styles['browser-extension-message']}>
298235
<span>
299-
+ <i title="Style of generated code blocks">edit format</i>{' '}
300-
instructions:
236+
Get the Connector browser extension for hands-free chat
237+
inititalizations
301238
</span>
302-
<UiHorizontalSelector
303-
options={[
304-
{
305-
value: 'whole',
306-
label: 'whole',
307-
title:
308-
'The model will output modified files in full. The best quality, especially from smaller models.'
309-
},
310-
{
311-
value: 'truncated',
312-
label: 'truncated',
313-
title:
314-
'The model will skip unchanged fragments in modified files. Readable but requires Intelligent Update API tool to apply.'
315-
},
316-
{
317-
value: 'diff',
318-
label: 'diff',
319-
title:
320-
'The model will output patches. Less readable but fast to apply. Smaller models may struggle with diff correctness.'
321-
}
322-
]}
323-
selected_value={
324-
props.home_view_type == HOME_VIEW_TYPES.WEB
325-
? props.chat_edit_format
326-
: props.api_edit_format
327-
}
328-
on_select={(value) =>
329-
props.home_view_type == HOME_VIEW_TYPES.WEB
330-
? props.on_chat_edit_format_change(value as EditFormat)
331-
: props.on_api_edit_format_change(value as EditFormat)
332-
}
333-
/>
239+
<a href="https://chromewebstore.google.com/detail/code-web-chat-connector/ljookipcanaglfaocjbgdicfbdhhjffp">
240+
Chrome Web Store ↗
241+
</a>
242+
<a href="https://addons.mozilla.org/en-US/firefox/addon/gemini-coder-connector/">
243+
Firefox Add-ons ↗
244+
</a>
334245
</div>
246+
247+
<UiSeparator height={8} />
335248
</>
336249
)}
337250

338-
{props.home_view_type == HOME_VIEW_TYPES.WEB && (
339-
<>
340-
<UiSeparator height={16} />
341-
<UiPresets
342-
presets={props.presets.map((preset) => {
343-
return {
344-
...preset,
345-
has_affixes: !!(
346-
preset.prompt_prefix || preset.prompt_suffix
347-
)
251+
<div className={styles['chat-input']}>
252+
<UiChatInput
253+
value={current_prompt}
254+
chat_history={props.chat_history}
255+
on_change={handle_input_change}
256+
on_submit={handle_submit}
257+
on_submit_with_control={handle_submit_with_control}
258+
on_copy={
259+
props.home_view_type == HOME_VIEW_TYPES.WEB &&
260+
props.web_mode != 'no-context'
261+
? handle_copy
262+
: undefined
263+
}
264+
on_search_click={props.on_search_click}
265+
on_at_sign_click={props.on_at_sign_click}
266+
is_web_mode={props.home_view_type == HOME_VIEW_TYPES.WEB}
267+
is_connected={props.is_connected}
268+
token_count={estimated_input_tokens}
269+
submit_disabled_title={
270+
!props.is_connected
271+
? 'WebSocket connection not established. Please install the browser extension.'
272+
: 'Type something'
273+
}
274+
is_in_code_completions_mode={is_in_code_completions_mode}
275+
has_active_selection={props.has_active_selection}
276+
has_active_editor={props.has_active_editor}
277+
on_caret_position_change={props.on_caret_position_change}
278+
translations={{
279+
type_something: 'Type something',
280+
completion_instructions: 'Completion instructions',
281+
send_request: 'Send request',
282+
initialize_chat: 'Initialize chat',
283+
select_preset: 'Select preset',
284+
select_config: 'Select config',
285+
code_completions_mode_unavailable_with_text_selection:
286+
'Unable to work with text selection',
287+
code_completions_mode_unavailable_without_active_editor:
288+
'This mode requires active editor',
289+
search: 'Search history'
290+
}}
291+
/>
292+
</div>
293+
294+
{((props.home_view_type == HOME_VIEW_TYPES.WEB &&
295+
props.web_mode == 'edit') ||
296+
(props.home_view_type == HOME_VIEW_TYPES.API &&
297+
props.api_mode == 'edit')) && (
298+
<>
299+
<div className={styles['edit-format']}>
300+
<span>
301+
+ <i title="Style of generated code blocks">edit format</i>{' '}
302+
instructions:
303+
</span>
304+
<UiHorizontalSelector
305+
options={[
306+
{
307+
value: 'whole',
308+
label: 'whole',
309+
title:
310+
'The model will output modified files in full. The best quality, especially from smaller models.'
311+
},
312+
{
313+
value: 'truncated',
314+
label: 'truncated',
315+
title:
316+
'The model will skip unchanged fragments in modified files. Readable but requires Intelligent Update API tool to apply.'
317+
},
318+
{
319+
value: 'diff',
320+
label: 'diff',
321+
title:
322+
'The model will output patches. Less readable but fast to apply. Smaller models may struggle with diff correctness.'
348323
}
349-
})}
350-
is_disabled={!props.is_connected}
351-
selected_presets={props.selected_presets}
352-
on_create_preset={props.on_create_preset}
353-
on_preset_click={(name) => {
354-
props.initialize_chats({
355-
prompt: current_prompt,
356-
preset_names: [name]
357-
})
358-
}}
359-
on_preset_copy={handle_preset_copy}
360-
on_preset_edit={props.on_preset_edit}
361-
on_presets_reorder={props.on_presets_reorder}
362-
on_preset_duplicate={props.on_preset_duplicate}
363-
on_preset_delete={props.on_preset_delete}
364-
on_set_default_presets={props.on_set_default_presets}
324+
]}
325+
selected_value={
326+
props.home_view_type == HOME_VIEW_TYPES.WEB
327+
? props.chat_edit_format
328+
: props.api_edit_format
329+
}
330+
on_select={(value) =>
331+
props.home_view_type == HOME_VIEW_TYPES.WEB
332+
? props.on_chat_edit_format_change(value as EditFormat)
333+
: props.on_api_edit_format_change(value as EditFormat)
334+
}
365335
/>
366-
</>
367-
)}
336+
</div>
337+
</>
338+
)}
339+
340+
{props.home_view_type == HOME_VIEW_TYPES.WEB && (
341+
<>
342+
<UiSeparator height={16} />
343+
<UiPresets
344+
presets={props.presets.map((preset) => {
345+
return {
346+
...preset,
347+
has_affixes: !!(
348+
preset.prompt_prefix || preset.prompt_suffix
349+
)
350+
}
351+
})}
352+
is_disabled={!props.is_connected}
353+
selected_presets={props.selected_presets}
354+
on_create_preset={props.on_create_preset}
355+
on_preset_click={(name) => {
356+
props.initialize_chats({
357+
prompt: current_prompt,
358+
preset_names: [name]
359+
})
360+
}}
361+
on_preset_copy={handle_preset_copy}
362+
on_preset_edit={props.on_preset_edit}
363+
on_presets_reorder={props.on_presets_reorder}
364+
on_preset_duplicate={props.on_preset_duplicate}
365+
on_preset_delete={props.on_preset_delete}
366+
on_set_default_presets={props.on_set_default_presets}
367+
/>
368+
</>
369+
)}
368370
</div>
369371
</Scrollable>
370372
<div

0 commit comments

Comments
 (0)