|
1 | 1 | <script> |
2 | | - import { Alert, Button, EmptyState, Group, Toast } from '@sveltia/ui'; |
| 2 | + import { |
| 3 | + Alert, |
| 4 | + Button, |
| 5 | + EmptyState, |
| 6 | + Group, |
| 7 | + ResizableHandle, |
| 8 | + ResizablePane, |
| 9 | + ResizablePaneGroup, |
| 10 | + Toast, |
| 11 | + } from '@sveltia/ui'; |
3 | 12 | import { onMount, tick, untrack } from 'svelte'; |
4 | 13 | import { _ } from 'svelte-i18n'; |
5 | 14 |
|
|
65 | 74 | const limit = $derived(entryCollection?.limit ?? Infinity); |
66 | 75 | const createDisabled = $derived(!canCreateEntry(collection)); |
67 | 76 |
|
| 77 | + const [firstPaneSize, secondPaneSize, minPaneSize] = $derived.by(() => { |
| 78 | + if ( |
| 79 | + typeof $editorFirstPane?.width === 'number' && |
| 80 | + typeof $editorSecondPane?.width === 'number' && |
| 81 | + $editorFirstPane.width >= 30 && |
| 82 | + $editorSecondPane.width >= 30 && |
| 83 | + $editorFirstPane.width + $editorSecondPane.width === 100 |
| 84 | + ) { |
| 85 | + return [$editorFirstPane.width, $editorSecondPane.width, 30]; |
| 86 | + } |
| 87 | +
|
| 88 | + if (!$editorFirstPane && !$editorSecondPane) { |
| 89 | + return [0, 0, 0]; |
| 90 | + } |
| 91 | +
|
| 92 | + if (!$editorFirstPane || !$editorSecondPane) { |
| 93 | + return [$editorFirstPane ? 100 : 0, $editorSecondPane ? 100 : 0, 0]; |
| 94 | + } |
| 95 | +
|
| 96 | + return [50, 50, 30]; |
| 97 | + }); |
| 98 | +
|
68 | 99 | /** |
69 | 100 | * Restore the pane state from IndexedDB. |
70 | 101 | * @returns {Promise<boolean>} Whether the panes are restored. |
|
97 | 128 | restoring = true; |
98 | 129 | await tick(); |
99 | 130 | $editorFirstPane = _editorFirstPane; |
100 | | - $editorSecondPane = _editorSecondPane; |
| 131 | + $editorSecondPane = $isSmallScreen || $isMediumScreen ? null : _editorSecondPane; |
101 | 132 | await tick(); |
102 | 133 | restoring = false; |
103 | 134 |
|
104 | | - if ($isSmallScreen || $isMediumScreen) { |
105 | | - $editorSecondPane = null; |
106 | | - } |
107 | | -
|
108 | 135 | return true; |
109 | 136 | }; |
110 | 137 |
|
|
212 | 239 | }); |
213 | 240 | </script> |
214 | 241 |
|
| 242 | +{#snippet firstPane()} |
| 243 | + {#if $editorFirstPane} |
| 244 | + {@const { locale, mode } = $editorFirstPane} |
| 245 | + <div class="pane-wrapper"> |
| 246 | + <Group |
| 247 | + class="pane" |
| 248 | + aria-label={$_(mode === 'edit' ? 'edit_x_locale' : 'preview_x_locale', { |
| 249 | + values: { locale: getLocaleLabel(locale) ?? locale }, |
| 250 | + })} |
| 251 | + data-locale={locale} |
| 252 | + data-mode={mode} |
| 253 | + > |
| 254 | + <PaneHeader id="first-pane-header" thisPane={editorFirstPane} thatPane={editorSecondPane} /> |
| 255 | + <PaneBody |
| 256 | + id="first-pane-body" |
| 257 | + thisPane={editorFirstPane} |
| 258 | + bind:thisPaneContentArea={firstPaneContentArea} |
| 259 | + bind:thatPaneContentArea={secondPaneContentArea} |
| 260 | + /> |
| 261 | + </Group> |
| 262 | + </div> |
| 263 | + {/if} |
| 264 | +{/snippet} |
| 265 | +
|
| 266 | +{#snippet secondPane()} |
| 267 | + {#if $editorSecondPane} |
| 268 | + {@const { locale, mode } = $editorSecondPane} |
| 269 | + <div class="pane-wrapper"> |
| 270 | + <Group |
| 271 | + aria-label={$_(mode === 'edit' ? 'edit_x_locale' : 'preview_x_locale', { |
| 272 | + values: { locale: getLocaleLabel(locale) ?? locale }, |
| 273 | + })} |
| 274 | + data-locale={locale} |
| 275 | + data-mode={mode} |
| 276 | + > |
| 277 | + <PaneHeader |
| 278 | + id="second-pane-header" |
| 279 | + thisPane={editorSecondPane} |
| 280 | + thatPane={editorFirstPane} |
| 281 | + /> |
| 282 | + <PaneBody |
| 283 | + id="second-pane-body" |
| 284 | + thisPane={editorSecondPane} |
| 285 | + bind:thisPaneContentArea={secondPaneContentArea} |
| 286 | + bind:thatPaneContentArea={firstPaneContentArea} |
| 287 | + /> |
| 288 | + </Group> |
| 289 | + </div> |
| 290 | + {/if} |
| 291 | +{/snippet} |
| 292 | +
|
215 | 293 | <div |
216 | 294 | role="group" |
217 | 295 | class="wrapper content-editor" |
|
248 | 326 | </div> |
249 | 327 | </EmptyState> |
250 | 328 | {:else} |
251 | | - <div role="none" class="cols"> |
252 | | - {#if collection} |
253 | | - {#if $editorFirstPane} |
254 | | - <!-- Somehow we need a fallback object or we’ll get a property destructuring error --> |
255 | | - {@const { locale, mode } = $editorFirstPane ?? {}} |
256 | | - <Group |
257 | | - class="pane" |
258 | | - aria-label={$_(mode === 'edit' ? 'edit_x_locale' : 'preview_x_locale', { |
259 | | - values: { locale: getLocaleLabel(locale) ?? locale }, |
260 | | - })} |
261 | | - data-locale={locale} |
262 | | - data-mode={mode} |
263 | | - > |
264 | | - <PaneHeader |
265 | | - id="first-pane-header" |
266 | | - thisPane={editorFirstPane} |
267 | | - thatPane={editorSecondPane} |
268 | | - /> |
269 | | - <PaneBody |
270 | | - id="first-pane-body" |
271 | | - thisPane={editorFirstPane} |
272 | | - bind:thisPaneContentArea={firstPaneContentArea} |
273 | | - bind:thatPaneContentArea={secondPaneContentArea} |
274 | | - /> |
275 | | - </Group> |
276 | | - {/if} |
277 | | - {#if $editorSecondPane} |
278 | | - <!-- Ditto --> |
279 | | - {@const { locale, mode } = $editorSecondPane ?? {}} |
280 | | - <Group |
281 | | - aria-label={$_(mode === 'edit' ? 'edit_x_locale' : 'preview_x_locale', { |
282 | | - values: { locale: getLocaleLabel(locale) ?? locale }, |
283 | | - })} |
284 | | - data-locale={locale} |
285 | | - data-mode={mode} |
286 | | - > |
287 | | - <PaneHeader |
288 | | - id="second-pane-header" |
289 | | - thisPane={editorSecondPane} |
290 | | - thatPane={editorFirstPane} |
291 | | - /> |
292 | | - <PaneBody |
293 | | - id="second-pane-body" |
294 | | - thisPane={editorSecondPane} |
295 | | - bind:thisPaneContentArea={secondPaneContentArea} |
296 | | - bind:thatPaneContentArea={firstPaneContentArea} |
297 | | - /> |
298 | | - </Group> |
299 | | - {/if} |
| 329 | + {#key collection} |
| 330 | + {#if $editorFirstPane && $editorSecondPane && firstPaneSize && secondPaneSize} |
| 331 | + <ResizablePaneGroup |
| 332 | + onResize={({ sizes }) => { |
| 333 | + if ($editorFirstPane && $editorSecondPane) { |
| 334 | + [$editorFirstPane.width, $editorSecondPane.width] = sizes; |
| 335 | + } |
| 336 | + }} |
| 337 | + > |
| 338 | + <ResizablePane defaultSize={firstPaneSize} minSize={minPaneSize}> |
| 339 | + {@render firstPane()} |
| 340 | + </ResizablePane> |
| 341 | + <ResizableHandle /> |
| 342 | + <ResizablePane defaultSize={secondPaneSize} minSize={minPaneSize}> |
| 343 | + {@render secondPane()} |
| 344 | + </ResizablePane> |
| 345 | + </ResizablePaneGroup> |
| 346 | + {:else if $editorFirstPane} |
| 347 | + {@render firstPane()} |
| 348 | + {:else if $editorSecondPane} |
| 349 | + {@render secondPane()} |
300 | 350 | {/if} |
301 | | - </div> |
| 351 | + {/key} |
302 | 352 | {/if} |
303 | 353 | {/key} |
304 | 354 | </div> |
|
320 | 370 | flex-direction: column; |
321 | 371 | background-color: var(--sui-secondary-background-color); |
322 | 372 |
|
323 | | - .cols { |
324 | | - flex: auto; |
325 | | - overflow: hidden; |
326 | | - display: flex; |
327 | | - gap: 4px; |
328 | | - background-color: var(--sui-secondary-background-color); // same as toolbar |
329 | | -
|
330 | | - :global { |
331 | | - & > div { |
332 | | - display: flex; |
333 | | - flex-direction: column; |
334 | | - min-width: 480px; |
335 | | - background-color: var(--sui-primary-background-color); |
336 | | - transition: all 500ms; |
337 | | -
|
338 | | - &[data-mode='edit'] { |
339 | | - flex: 1 1; |
340 | | - } |
341 | | -
|
342 | | - &[data-mode='preview'] { |
343 | | - flex: 2 1; |
344 | | - } |
345 | | -
|
346 | | - @media (width < 768px) { |
347 | | - min-width: auto; |
348 | | - } |
349 | | - } |
| 373 | + :global { |
| 374 | + .sui.resizable-pane-group { |
| 375 | + background-color: var(--sui-secondary-background-color); // same as toolbar |
| 376 | + } |
| 377 | +
|
| 378 | + .sui.resizable-pane { |
| 379 | + background-color: var(--sui-primary-background-color); |
| 380 | + } |
| 381 | + } |
| 382 | + } |
| 383 | +
|
| 384 | + .pane-wrapper { |
| 385 | + display: contents; |
| 386 | +
|
| 387 | + :global { |
| 388 | + & > .group { |
| 389 | + height: 100%; |
| 390 | + overflow: hidden; |
| 391 | + display: flex; |
| 392 | + flex-direction: column; |
350 | 393 | } |
351 | 394 | } |
352 | 395 | } |
|
0 commit comments