@@ -6,6 +6,7 @@ import { editor as mEditor } from 'monaco-editor';
6
6
import { Preview } from './preview' ;
7
7
import { TabItem } from './tab/item' ;
8
8
import { TabList } from './tab/list' ;
9
+ import { GridResizer } from './gridResizer' ;
9
10
import { Error } from './error' ;
10
11
11
12
import type { Tab } from '../' ;
@@ -203,43 +204,78 @@ export const Repl: Component<ReplProps> = (props) => {
203
204
} ;
204
205
205
206
/**
206
- * This whole block before the slice of view
207
- * is an experimental resizer, need to tidy this up
207
+ * Upcomming 2 blocks before the slice of view is used for horizontal and vertical resizers.
208
+ * This first block controls the horizontal resizer.
208
209
*/
210
+ const adjustPercentage = ( percentage : number , lowerBound : number , upperBound : number ) => {
211
+ if ( percentage < lowerBound ) {
212
+ return lowerBound ;
213
+ } else if ( percentage > upperBound ) {
214
+ return upperBound ;
215
+ } else {
216
+ return percentage ;
217
+ }
218
+ } ;
219
+
220
+ const [ horizontalResizer , setHorizontalResizer ] = createSignal < HTMLElement > ( ) ;
209
221
const [ left , setLeft ] = createSignal ( 1.25 ) ;
210
- const [ isDragging , setIsDragging ] = createSignal ( false ) ;
211
222
212
- const onMouseMove = throttle ( ( e : MouseEvent ) => {
213
- const percentage = e . clientX / ( document . body . offsetWidth / 2 ) ;
214
- if ( percentage < 0.5 || percentage > 1.5 ) return ;
223
+ const changeLeft = ( clientX : number , _clientY : number ) => {
224
+ // Adjust the reading according to the width of the resizable panes
225
+ const clientXAdjusted = clientX - horizontalResizer ( ) ! . offsetWidth / 2 ;
226
+ const widthAdjusted = document . body . offsetWidth - horizontalResizer ( ) ! . offsetWidth ;
215
227
216
- setLeft ( percentage ) ;
217
- } , 10 ) ;
228
+ const percentage = clientXAdjusted / ( widthAdjusted / 2 ) ;
229
+ const percentageAdjusted = adjustPercentage ( percentage , 0.5 , 1.5 ) ;
218
230
219
- const onMouseUp = ( ) => setIsDragging ( false ) ;
231
+ setLeft ( percentageAdjusted ) ;
232
+ } ;
220
233
221
- createEffect ( ( ) => {
222
- if ( isDragging ( ) ) {
223
- window . addEventListener ( 'mousemove' , onMouseMove ) ;
224
- window . addEventListener ( 'mouseup' , onMouseUp ) ;
225
- } else {
226
- window . removeEventListener ( 'mousemove' , onMouseMove ) ;
227
- window . removeEventListener ( 'mouseup' , onMouseUp ) ;
228
- }
229
- } ) ;
234
+ /**
235
+ * This second block controls the vertical resizer.
236
+ */
237
+ const [ grid , setGrid ] = createSignal < HTMLElement > ( ) ;
238
+ const [ fileTabs , setFileTabs ] = createSignal < HTMLElement > ( ) ;
239
+ const [ resultTabs , setResultTabs ] = createSignal < HTMLElement > ( ) ;
240
+ const [ verticalResizer , setVerticalResizer ] = createSignal < HTMLElement > ( ) ;
241
+ const [ top , setTop ] = createSignal ( 1 ) ;
242
+
243
+ const changeTop = ( _clientX : number , clientY : number ) => {
244
+ // Adjust the reading according to the height of the resizable panes
245
+ const headerSize = document . body . offsetHeight - grid ( ) ! . offsetHeight ;
246
+ const clientYAdjusted =
247
+ clientY - headerSize - fileTabs ( ) ! . offsetHeight - verticalResizer ( ) ! . offsetHeight / 2 ;
248
+ const heightAdjusted =
249
+ document . body . offsetHeight -
250
+ headerSize -
251
+ fileTabs ( ) ! . offsetHeight -
252
+ verticalResizer ( ) ! . offsetHeight -
253
+ resultTabs ( ) ! . offsetHeight ;
254
+
255
+ const percentage = clientYAdjusted / ( heightAdjusted / 2 ) ;
256
+ const percentageAdjusted = adjustPercentage ( percentage , 0.5 , 1.5 ) ;
257
+
258
+ setTop ( percentageAdjusted ) ;
259
+ } ;
230
260
231
261
const [ reloadSignal , reload ] = createSignal ( false , { equals : false } ) ;
232
262
233
263
return (
234
264
< div
265
+ ref = { ( el ) => setGrid ( el ) }
235
266
class = "relative grid bg-blueGray-50 h-full overflow-hidden text-blueGray-900 dark:text-blueGray-50 font-sans"
236
267
classList = { {
237
268
'wrapper--forced' : props . isHorizontal ,
238
269
wrapper : ! props . isHorizontal ,
239
270
} }
240
- style = { { '--left' : `${ left ( ) } fr` , '--right' : `${ 2 - left ( ) } fr` } }
271
+ style = { {
272
+ '--left' : `${ left ( ) } fr` ,
273
+ '--right' : `${ 2 - left ( ) } fr` ,
274
+ '--top' : `${ top ( ) } fr` ,
275
+ '--bottom' : `${ 2 - top ( ) } fr` ,
276
+ } }
241
277
>
242
- < TabList class = "row-start-1 space-x-2" >
278
+ < TabList ref = { ( el ) => setFileTabs ( el ) } class = "row-start-1 space-x-2" >
243
279
< For each = { props . tabs } >
244
280
{ ( tab , index ) => (
245
281
< TabItem active = { props . current === id ( tab ) } >
@@ -345,7 +381,8 @@ export const Repl: Component<ReplProps> = (props) => {
345
381
</ TabList >
346
382
347
383
< TabList
348
- class = { `row-start-3 border-t-2 border-blueGray-200 ${
384
+ ref = { ( el ) => setResultTabs ( el ) }
385
+ class = { `row-start-4 border-blueGray-200 ${
349
386
props . isHorizontal ? '' : 'md:row-start-1 md:col-start-3 md:border-t-0'
350
387
} `}
351
388
>
@@ -404,18 +441,25 @@ export const Repl: Component<ReplProps> = (props) => {
404
441
ref = { props . onEditorReady }
405
442
/>
406
443
407
- < div
408
- class = "column-resizer h-full w-full row-start-1 row-end-3 col-start-2 hidden"
409
- style = "cursor: col-resize"
410
- classList = { { 'md:block' : ! props . isHorizontal } }
411
- onMouseDown = { [ setIsDragging , true ] }
412
- >
413
- < div class = "h-full border-blueGray-200 dark:border-blueGray-700 border-l border-r rounded-lg mx-auto w-0" > </ div >
414
- </ div >
444
+ < GridResizer
445
+ ref = { ( el ) => setVerticalResizer ( el ) }
446
+ isHorizontal = { props . isHorizontal }
447
+ direction = "vertical"
448
+ class = "row-start-3"
449
+ onResize = { changeTop }
450
+ />
451
+
452
+ < GridResizer
453
+ ref = { ( el ) => setHorizontalResizer ( el ) }
454
+ isHorizontal = { props . isHorizontal }
455
+ direction = "horizontal"
456
+ class = "row-start-1 row-end-3 col-start-2"
457
+ onResize = { changeLeft }
458
+ />
415
459
416
460
< Show when = { ! showPreview ( ) } >
417
461
< section
418
- class = "h-full max-h-screen bg-white dark:bg-blueGray-800 grid focus:outline-none row-start-4 relative divide-y-2 divide-blueGray-200 dark:divide-blueGray-500"
462
+ class = "h-full max-h-screen bg-white dark:bg-blueGray-800 grid focus:outline-none row-start-5 relative divide-y-2 divide-blueGray-200 dark:divide-blueGray-500"
419
463
classList = { { 'md:row-start-2' : ! props . isHorizontal } }
420
464
style = "grid-template-rows: minmax(0, 1fr) auto"
421
465
>
@@ -481,12 +525,9 @@ export const Repl: Component<ReplProps> = (props) => {
481
525
< Preview
482
526
reloadSignal = { reloadSignal ( ) }
483
527
code = { store . compiled }
484
- class = { `h-full w-full bg-white row-start-4 ${
528
+ class = { `h-full w-full bg-white row-start-5 ${
485
529
props . isHorizontal ? '' : 'md:row-start-2'
486
530
} `}
487
- classList = { {
488
- 'pointer-events-none' : isDragging ( ) ,
489
- } }
490
531
/>
491
532
</ Show >
492
533
</ Suspense >
0 commit comments