|
23 | 23 | $: isCheckboxChecked = /^\[x\]\s/.test(item.text || '') |
24 | 24 | $: displayText = hasCheckboxSyntax ? item.text.replace(/^\[( |x)\]\s/, '') : item.text |
25 | 25 | $: hasDescription = !!item.description?.trim() |
| 26 | + $: hasChildren = item.children?.length > 0 |
26 | 27 |
|
27 | 28 | function handleToggleComplete() { |
28 | 29 | if (hasCheckboxSyntax) { |
|
39 | 40 | dispatch('delete', { id: item.id }) |
40 | 41 | } |
41 | 42 |
|
| 43 | + function handleForceDelete() { |
| 44 | + dispatch('forcedelete', { id: item.id }) |
| 45 | + } |
| 46 | +
|
42 | 47 | function handleNewBullet() { |
43 | 48 | dispatch('newbullet', { id: item.id }) |
44 | 49 | } |
|
61 | 66 | dispatch('selectdown', { id: item.id }) |
62 | 67 | } |
63 | 68 |
|
| 69 | + function handleShiftSelectUp() { |
| 70 | + dispatch('shiftselectup', { id: item.id }) |
| 71 | + } |
| 72 | +
|
| 73 | + function handleShiftSelectDown() { |
| 74 | + dispatch('shiftselectdown', { id: item.id }) |
| 75 | + } |
| 76 | +
|
64 | 77 | function handleShowDescription() { |
65 | 78 | showDescriptionEditor = true |
66 | 79 | tick().then(() => { |
|
129 | 142 | class="item" |
130 | 143 | class:completed={item.completed || isCheckboxChecked} |
131 | 144 | class:selected={isSelected} |
132 | | - class:nochildren={!item.children?.length} |
133 | 145 | > |
134 | 146 | <div class="top"> |
135 | | - <div class="options"> |
| 147 | + <div class="left-controls"> |
136 | 148 | <button class="menu-trigger" on:click={handleMenuClick} title="Options"> |
137 | 149 | <svg width="16" height="16" viewBox="0 0 256 256"> |
138 | 150 | <path |
|
147 | 159 | on:close={() => showMenu = false} |
148 | 160 | /> |
149 | 161 | {/if} |
150 | | - {#if item.children?.length} |
151 | | - <Collapse |
152 | | - collapsed={!item.open} |
153 | | - on:change={handleToggleOpen} |
154 | | - /> |
155 | | - {/if} |
| 162 | + <div class="collapse-slot"> |
| 163 | + {#if hasChildren} |
| 164 | + <Collapse |
| 165 | + collapsed={!item.open} |
| 166 | + on:change={handleToggleOpen} |
| 167 | + /> |
| 168 | + {/if} |
| 169 | + </div> |
156 | 170 | </div> |
157 | 171 |
|
158 | | - <div class="bullets"> |
159 | | - <Bullet |
160 | | - background={!!item.children?.length && !item.open} |
161 | | - on:click={handleZoom} |
162 | | - /> |
163 | | - {#if hasCheckboxSyntax} |
164 | | - <Checkbox |
165 | | - checked={isCheckboxChecked} |
166 | | - on:click={handleToggleComplete} |
| 172 | + <div class="content-area"> |
| 173 | + <div class="bullet-line"> |
| 174 | + <Bullet |
| 175 | + background={hasChildren && !item.open} |
| 176 | + on:click={handleZoom} |
167 | 177 | /> |
| 178 | + {#if hasCheckboxSyntax} |
| 179 | + <Checkbox |
| 180 | + checked={isCheckboxChecked} |
| 181 | + on:click={handleToggleComplete} |
| 182 | + /> |
| 183 | + {/if} |
| 184 | + <div class="title-editor"> |
| 185 | + <RichEditor |
| 186 | + bind:this={titleEditorRef} |
| 187 | + value={displayText} |
| 188 | + showPlaceholder={false} |
| 189 | + {highlightPhrase} |
| 190 | + on:change={handleTextChange} |
| 191 | + on:delete={handleDelete} |
| 192 | + on:forcedelete={handleForceDelete} |
| 193 | + on:newbullet={handleNewBullet} |
| 194 | + on:indent={handleIndent} |
| 195 | + on:outdent={handleOutdent} |
| 196 | + on:selectup={handleSelectUp} |
| 197 | + on:selectdown={handleSelectDown} |
| 198 | + on:shiftselectup={handleShiftSelectUp} |
| 199 | + on:shiftselectdown={handleShiftSelectDown} |
| 200 | + on:togglecomplete={handleToggleComplete} |
| 201 | + on:description={handleShowDescription} |
| 202 | + on:hashtagclick={handleHashtagClick} |
| 203 | + /> |
| 204 | + </div> |
| 205 | + </div> |
| 206 | +
|
| 207 | + {#if hasDescription || showDescriptionEditor} |
| 208 | + <div class="description-editor"> |
| 209 | + <RichEditor |
| 210 | + bind:value={item.description} |
| 211 | + isDescription={true} |
| 212 | + showPlaceholder={false} |
| 213 | + {highlightPhrase} |
| 214 | + editorClass="editable description" |
| 215 | + on:change={handleDescriptionChange} |
| 216 | + on:delete={handleExitDescription} |
| 217 | + on:exitdescription={handleExitDescription} |
| 218 | + on:togglecomplete={handleToggleComplete} |
| 219 | + on:hashtagclick={handleHashtagClick} |
| 220 | + /> |
| 221 | + </div> |
168 | 222 | {/if} |
169 | 223 | </div> |
170 | | -
|
171 | | - <div class="title-editor"> |
172 | | - <RichEditor |
173 | | - bind:this={titleEditorRef} |
174 | | - value={displayText} |
175 | | - showPlaceholder={false} |
176 | | - {highlightPhrase} |
177 | | - on:change={handleTextChange} |
178 | | - on:delete={handleDelete} |
179 | | - on:newbullet={handleNewBullet} |
180 | | - on:indent={handleIndent} |
181 | | - on:outdent={handleOutdent} |
182 | | - on:selectup={handleSelectUp} |
183 | | - on:selectdown={handleSelectDown} |
184 | | - on:togglecomplete={handleToggleComplete} |
185 | | - on:description={handleShowDescription} |
186 | | - on:hashtagclick={handleHashtagClick} |
187 | | - /> |
188 | | - </div> |
189 | 224 | </div> |
190 | | -
|
191 | | - {#if hasDescription || showDescriptionEditor} |
192 | | - <div class="description-editor"> |
193 | | - <RichEditor |
194 | | - bind:value={item.description} |
195 | | - isDescription={true} |
196 | | - showPlaceholder={false} |
197 | | - {highlightPhrase} |
198 | | - editorClass="editable description" |
199 | | - on:change={handleDescriptionChange} |
200 | | - on:delete={handleExitDescription} |
201 | | - on:exitdescription={handleExitDescription} |
202 | | - on:togglecomplete={handleToggleComplete} |
203 | | - on:hashtagclick={handleHashtagClick} |
204 | | - /> |
205 | | - </div> |
206 | | - {/if} |
207 | 225 | </li> |
208 | 226 |
|
209 | 227 | <style> |
|
215 | 233 | flex-direction: column; |
216 | 234 | } |
217 | 235 |
|
218 | | - .nochildren .options { |
219 | | - min-width: 1rem; |
220 | | - } |
221 | | -
|
222 | 236 | .completed :global(.title-editor .editable) { |
223 | 237 | text-decoration: line-through; |
224 | 238 | opacity: 0.6; |
225 | 239 | } |
226 | 240 |
|
227 | 241 | .selected { |
228 | | - background: rgba(73, 186, 242, 0.1); |
| 242 | + background: rgba(73, 186, 242, 0.15); |
229 | 243 | border-radius: 4px; |
230 | 244 | } |
231 | 245 |
|
|
235 | 249 | width: 100%; |
236 | 250 | } |
237 | 251 |
|
238 | | - .options { |
| 252 | + .left-controls { |
239 | 253 | display: flex; |
240 | 254 | align-items: center; |
241 | | - min-width: 1.8rem; |
| 255 | + flex-shrink: 0; |
242 | 256 | position: relative; |
243 | 257 | } |
244 | 258 |
|
| 259 | + .collapse-slot { |
| 260 | + width: 1rem; |
| 261 | + display: flex; |
| 262 | + align-items: center; |
| 263 | + justify-content: center; |
| 264 | + } |
| 265 | +
|
245 | 266 | .menu-trigger { |
246 | 267 | all: unset; |
247 | 268 | cursor: pointer; |
|
263 | 284 | color: #666 !important; |
264 | 285 | } |
265 | 286 |
|
266 | | - .bullets { |
| 287 | + .content-area { |
| 288 | + flex: 1; |
| 289 | + min-width: 0; |
| 290 | + display: flex; |
| 291 | + flex-direction: column; |
| 292 | + } |
| 293 | +
|
| 294 | + .bullet-line { |
267 | 295 | display: flex; |
268 | 296 | align-items: center; |
269 | | - flex-shrink: 0; |
270 | 297 | } |
271 | 298 |
|
272 | 299 | .title-editor { |
|
275 | 302 | } |
276 | 303 |
|
277 | 304 | .description-editor { |
278 | | - margin-left: 2.8rem; |
| 305 | + margin-left: 1.3rem; |
279 | 306 | font-size: 0.85rem; |
280 | 307 | } |
281 | 308 | </style> |
0 commit comments