Skip to content

Commit 3e0af64

Browse files
committed
Add compact mode and sticky positioning for mode buttons with task list enhancements
1 parent 256c952 commit 3e0af64

4 files changed

Lines changed: 163 additions & 40 deletions

File tree

‎packages/ui/src/components/editor/panel/ModeButton/ModeButton.module.scss‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@
1919
padding: 0 12px;
2020
height: 80px;
2121

22+
&--compact {
23+
height: 36px;
24+
gap: 8px;
25+
26+
.button__pre {
27+
display: none;
28+
}
29+
30+
.button__label {
31+
font-size: 18px;
32+
}
33+
}
34+
2235
&:hover {
2336
background-color: var(--vscode-toolbar-hoverBackground);
2437
border-color: transparent;

‎packages/ui/src/components/editor/panel/ModeButton/ModeButton.tsx‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
import styles from './ModeButton.module.scss'
2+
import cn from 'classnames'
23

34
type Props = {
45
label: string
56
pre: React.ReactNode
67
on_click: () => void
8+
is_compact?: boolean
79
}
810

911
export const ModeButton: React.FC<Props> = (props) => {
1012
return (
11-
<button className={styles.button} onClick={props.on_click}>
13+
<button
14+
className={cn(styles.button, {
15+
[styles['button--compact']]: props.is_compact
16+
})}
17+
onClick={props.on_click}
18+
>
1219
<div className={styles['button__pre']}>{props.pre}</div>
1320
<div className={styles['button__label']}>
1421
{props.label.split('').map((char, index) => (

‎packages/vscode/src/views/panel/frontend/Home/Home.module.scss‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@
8989
border: 1px solid var(--cwc-border-color);
9090
overflow: hidden;
9191
margin: 0 12px;
92+
z-index: 10;
93+
94+
&--sticky {
95+
position: sticky;
96+
top: 10px;
97+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
98+
animation: stickyFadeIn var(--transition-duration-150) var(--transition-timing-function)
99+
}
92100

93101
> button {
94102
flex: 1;
@@ -124,6 +132,9 @@
124132
}
125133

126134
&__tasks-header {
135+
display: flex;
136+
align-items: center;
137+
justify-content: space-between;
127138
padding: 1px 12px 0px 12px;
128139
font-size: 11px;
129140
font-weight: bold;
@@ -154,3 +165,47 @@
154165
text-decoration: underline;
155166
}
156167
}
168+
169+
@keyframes stickyFadeIn {
170+
from {
171+
opacity: 0;
172+
transform: translateY(-10px);
173+
}
174+
to {
175+
opacity: 1;
176+
transform: translateY(0);
177+
}
178+
}
179+
180+
.add-button {
181+
appearance: none;
182+
background: none;
183+
border: none;
184+
padding: 0;
185+
margin: 0;
186+
height: 16px;
187+
width: 16px;
188+
color: var(--vscode-icon-foreground);
189+
position: relative;
190+
cursor: pointer;
191+
flex-shrink: 0;
192+
193+
&:focus {
194+
outline: none;
195+
}
196+
197+
&::before {
198+
font-family: 'codicon';
199+
font-size: 14px;
200+
content: '\ea60';
201+
position: absolute;
202+
top: 50%;
203+
left: 50%;
204+
transform: translate(-50%, -50%);
205+
opacity: 0.6;
206+
}
207+
208+
&:hover::before {
209+
opacity: 1;
210+
}
211+
}

‎packages/vscode/src/views/panel/frontend/Home/Home.tsx‎

Lines changed: 87 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useState, useRef } from 'react'
12
import styles from './Home.module.scss'
23
import { Scrollable } from '@ui/components/editor/panel/Scrollable'
34
import { Timeline } from '@ui/components/editor/panel/Timeline'
@@ -43,6 +44,9 @@ type Props = {
4344

4445
export const Home: React.FC<Props> = (props) => {
4546
const { t } = use_translation()
47+
const [is_mode_sticky, set_is_mode_sticky] = useState(false)
48+
const responses_ref = useRef<HTMLDivElement>(null)
49+
const mode_ref = useRef<HTMLDivElement>(null)
4650

4751
const {
4852
handle_reorder,
@@ -93,11 +97,17 @@ export const Home: React.FC<Props> = (props) => {
9397
</button>
9498
</div>
9599

96-
<Scrollable>
100+
<Scrollable
101+
on_scroll={(top) => {
102+
const responses_height = responses_ref.current?.clientHeight || 0
103+
const mode_height = mode_ref.current?.clientHeight || 0
104+
set_is_mode_sticky(top > responses_height + mode_height + 4)
105+
}}
106+
>
97107
<div className={styles.content}>
98108
<div className={styles.inner}>
99109
{props.response_history.length > 0 && (
100-
<div className={styles.inner__responses}>
110+
<div className={styles.inner__responses} ref={responses_ref}>
101111
<UiResponses
102112
response_history={props.response_history}
103113
on_response_history_item_click={
@@ -112,20 +122,27 @@ export const Home: React.FC<Props> = (props) => {
112122
on_response_history_item_remove={
113123
props.on_response_history_item_remove
114124
}
115-
/>{' '}
125+
/>
116126
</div>
117127
)}
118128

119-
<div className={styles.inner__mode}>
129+
<div
130+
className={cn(styles.inner__mode, {
131+
[styles['inner__mode--sticky']]: is_mode_sticky
132+
})}
133+
ref={mode_ref}
134+
>
120135
<ModeButton
121136
pre="Autofill"
122137
label="Chatbots"
123138
on_click={props.on_chatbots_click}
139+
is_compact={is_mode_sticky}
124140
/>
125141
<ModeButton
126142
pre="Make"
127143
label="API calls"
128144
on_click={props.on_api_calls_click}
145+
is_compact={is_mode_sticky}
129146
/>
130147
</div>
131148

@@ -137,52 +154,83 @@ export const Home: React.FC<Props> = (props) => {
137154
on_toggle_collapsed={() =>
138155
props.on_tasks_collapsed_change(!props.are_tasks_collapsed)
139156
}
157+
actions={
158+
Object.keys(props.tasks).length == 1 ? (
159+
<IconButton
160+
codicon_icon="add"
161+
title="Add Task"
162+
on_click={(e) => {
163+
e.stopPropagation()
164+
const roots = Object.keys(props.tasks)
165+
if (roots.length > 0) {
166+
handle_add(roots[0], props.tasks[roots[0]], 'top')
167+
if (props.are_tasks_collapsed) {
168+
props.on_tasks_collapsed_change(false)
169+
}
170+
}
171+
}}
172+
/>
173+
) : undefined
174+
}
140175
/>
141176
{!props.are_tasks_collapsed &&
142-
Object.entries(props.tasks).map(
143-
([workspace_root_folder, tasks], _, entries) => (
177+
Object.entries(props.tasks)
178+
.filter(([_, tasks], __, arr) =>
179+
arr.length == 1 ? tasks.length : true
180+
)
181+
.map(([workspace_root_folder, tasks], _, entries) => (
144182
<div
145183
key={workspace_root_folder}
146184
className={styles.inner__tasks}
147185
>
148186
{entries.length > 1 && (
149187
<div className={styles['inner__tasks-header']}>
150-
{workspace_root_folder.split(/[\\/]/).pop() ||
151-
workspace_root_folder}
188+
<span>
189+
{workspace_root_folder.split(/[\\/]/).pop() ||
190+
workspace_root_folder}
191+
</span>
192+
<button
193+
className={styles['add-button']}
194+
title="Add Task"
195+
onClick={() => {
196+
handle_add(workspace_root_folder, tasks, 'top')
197+
}}
198+
/>
152199
</div>
153200
)}
154-
<Tasks
155-
tasks={tasks}
156-
on_reorder={(new_tasks) =>
157-
handle_reorder(workspace_root_folder, new_tasks)
158-
}
159-
on_change={(updated_task) => {
160-
handle_change(
161-
workspace_root_folder,
162-
tasks,
163-
updated_task
164-
)
165-
}}
166-
on_add={() => {
167-
handle_add(workspace_root_folder, tasks)
168-
}}
169-
on_add_subtask={(parent_task) => {
170-
handle_add_subtask(
171-
workspace_root_folder,
172-
tasks,
173-
parent_task
174-
)
175-
}}
176-
on_delete={(timestamp) => {
177-
handle_delete(workspace_root_folder, timestamp)
178-
}}
179-
on_copy={(text) => {
180-
handle_copy(text)
181-
}}
182-
/>
201+
{tasks.length > 0 && (
202+
<Tasks
203+
tasks={tasks}
204+
on_reorder={(new_tasks) =>
205+
handle_reorder(workspace_root_folder, new_tasks)
206+
}
207+
on_change={(updated_task) => {
208+
handle_change(
209+
workspace_root_folder,
210+
tasks,
211+
updated_task
212+
)
213+
}}
214+
on_add={() => {
215+
handle_add(workspace_root_folder, tasks)
216+
}}
217+
on_add_subtask={(parent_task) => {
218+
handle_add_subtask(
219+
workspace_root_folder,
220+
tasks,
221+
parent_task
222+
)
223+
}}
224+
on_delete={(timestamp) => {
225+
handle_delete(workspace_root_folder, timestamp)
226+
}}
227+
on_copy={(text) => {
228+
handle_copy(text)
229+
}}
230+
/>
231+
)}
183232
</div>
184-
)
185-
)}
233+
))}
186234

187235
<ListHeader
188236
title="Timeline"

0 commit comments

Comments
 (0)