Skip to content

Commit 7bc4701

Browse files
authored
feat(ui): NSplitPane component (#438)
1 parent 05efb95 commit 7bc4701

12 files changed

Lines changed: 902 additions & 154 deletions

File tree

packages/devtools-ui-kit/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"@vueuse/nuxt": "^10.4.1",
5252
"defu": "^6.1.2",
5353
"focus-trap": "^7.5.3",
54+
"splitpanes": "^3.1.5",
5455
"unocss": "^0.56.2",
5556
"v-lazy-show": "^0.2.3"
5657
},
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<script setup lang="ts">
2+
import { computed, ref } from 'vue'
3+
import { useLocalStorage } from '@vueuse/core'
4+
import { Pane, Splitpanes } from 'splitpanes'
5+
6+
import 'splitpanes/dist/splitpanes.css'
7+
8+
const props = withDefaults(defineProps<{
9+
/**
10+
* The key to use for storing the pane sizes in localStorage.
11+
*/
12+
storageKey?: string
13+
stateKey?: string
14+
leftSize?: number
15+
minSize?: number
16+
horizontal?: boolean
17+
}>(), {
18+
stateKey: 'nuxt-devtools-panels-state',
19+
})
20+
21+
const state = useLocalStorage<Record<string, number>>(props.stateKey, {} as any, { listenToStorageChanges: false })
22+
23+
const DEFAULT = 30
24+
25+
const key = props.storageKey
26+
const size = key
27+
? computed({
28+
get: () => state.value[key] || props.leftSize || DEFAULT,
29+
set: (v) => { state.value[key] = v },
30+
})
31+
: ref(props.leftSize || DEFAULT)
32+
</script>
33+
34+
<template>
35+
<Splitpanes :horizontal="horizontal" h-full of-hidden @resize="size = $event[0].size">
36+
<Pane h-full class="of-auto!" :size="size" :min-size="$slots.right ? (minSize || 10) : 100">
37+
<slot name="left" />
38+
</Pane>
39+
<Pane v-if="$slots.right" relative h-full class="of-auto!" :min-size="minSize || 10">
40+
<slot name="right" />
41+
</Pane>
42+
</Splitpanes>
43+
</template>
44+
45+
<style>
46+
.splitpanes__splitter {
47+
position: relative;
48+
}
49+
.splitpanes__splitter:before {
50+
position: absolute;
51+
left: 0;
52+
top: 0;
53+
transition: .2s ease;
54+
content: '';
55+
transition: opacity 0.4s;
56+
z-index: 1;
57+
}
58+
.splitpanes__splitter:hover:before {
59+
background: #8881;
60+
opacity: 1;
61+
}
62+
.splitpanes--vertical>.splitpanes__splitter {
63+
min-width: 0 !important;
64+
width: 0 !important;
65+
@apply border-r border-base
66+
}
67+
.splitpanes--horizontal>.splitpanes__splitter {
68+
min-height: 0 !important;
69+
height: 0 !important;
70+
@apply border-t border-base
71+
}
72+
.splitpanes--vertical>.splitpanes__splitter:before {
73+
left: -5px;
74+
right: -4px;
75+
height: 100%;
76+
}
77+
.splitpanes--horizontal>.splitpanes__splitter:before {
78+
top: -5px;
79+
bottom: -4px;
80+
width: 100%;
81+
}
82+
</style>

packages/devtools/client/app.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script setup lang="ts">
22
import 'floating-vue/dist/style.css'
33
import 'vanilla-jsoneditor/themes/jse-theme-dark.css'
4-
import 'splitpanes/dist/splitpanes.css'
54
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
65
import './styles/global.css'
76
import { setupClientRPC } from './setup/client-rpc'
@@ -94,14 +93,14 @@ registerCommands(() =>
9493
>
9594
<SideNav v-show="!isUtilityView" of-x-hidden of-y-auto />
9695
<NuxtLayout>
97-
<PanelLeftRight storage-key="devtools:split-screen-mode" :min-size="20">
96+
<NSplitPane storage-key="devtools:split-screen-mode" :min-size="20">
9897
<template #left>
9998
<NuxtPage />
10099
</template>
101100
<template v-if="splitScreenEnabled && splitScreenAvailable" #right>
102101
<SplitScreen />
103102
</template>
104-
</PanelLeftRight>
103+
</NSplitPane>
105104
</NuxtLayout>
106105
<CommandPalette />
107106
<AuthConfirmDialog />

packages/devtools/client/components/PanelLeftRight.vue

Lines changed: 0 additions & 34 deletions
This file was deleted.

packages/devtools/client/components/StorageDetails.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ async function renameCurrentItem() {
109109
</script>
110110

111111
<template>
112-
<PanelLeftRight v-if="currentStorage" storage-key="tab-storage">
112+
<NSplitPane v-if="currentStorage" storage-key="tab-storage">
113113
<template #left>
114114
<div class="h-[48px] flex items-center justify-between gap1 px-3">
115115
<NIconButton icon="carbon-chevron-left" ml--1 @click="currentStorage = ''" />
@@ -189,7 +189,7 @@ async function renameCurrentItem() {
189189
</NCard>
190190
</NPanelGrids>
191191
</template>
192-
</PanelLeftRight>
192+
</NSplitPane>
193193
<NPanelGrids v-else>
194194
<p v-if="Object.keys(storageMounts as any).length" op50>
195195
Select one storage to start:

packages/devtools/client/pages/modules/analyze-build.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ registerCommands(() => [
6363
</script>
6464

6565
<template>
66-
<PanelLeftRight :left-size="30">
66+
<NSplitPane :left-size="30">
6767
<template #left>
6868
<div flex="~ col">
6969
<template v-for="build of info?.builds" :key="build.slug">
@@ -96,7 +96,7 @@ registerCommands(() => [
9696
<BuildAnalyzeDetails v-if="selected" :current="selected" />
9797
<NPanelGrids v-else />
9898
</template>
99-
</PanelLeftRight>
99+
</NSplitPane>
100100

101101
<PromiseConfirm v-slot="{ resolve }">
102102
<NDialog :model-value="true" @close="resolve(false)">

packages/devtools/client/pages/modules/server-routes.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ function capitalize(str: string) {
131131
</script>
132132

133133
<template>
134-
<PanelLeftRight storage-key="tab-server-routes">
134+
<NSplitPane storage-key="tab-server-routes">
135135
<template #left>
136136
<Navbar v-model:search="search" pb2>
137137
<template #actions>
@@ -177,7 +177,7 @@ function capitalize(str: string) {
177177
</NCard>
178178
</NPanelGrids>
179179
</template>
180-
</PanelLeftRight>
180+
</NSplitPane>
181181
<NDrawer v-model="inputDefaultsDrawer" auto-close max-w-xl min-w-xl @close="inputDefaultsDrawer = false">
182182
<div>
183183
<div p4 border="b base">

packages/devtools/client/pages/modules/virtual-files.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const filteredFiles = computed(() => {
6161
</script>
6262

6363
<template>
64-
<PanelLeftRight class="virtual-files" storage-key="tab-virtual-files">
64+
<NSplitPane class="virtual-files" storage-key="tab-virtual-files">
6565
<template #left>
6666
<Navbar
6767
v-model:search="searchString"
@@ -94,7 +94,7 @@ const filteredFiles = computed(() => {
9494
</NCard>
9595
</NPanelGrids>
9696
</template>
97-
</PanelLeftRight>
97+
</NSplitPane>
9898

9999
<HelpFab>
100100
<DocsVirtualFiles />

packages/devtools/client/styles/global.css

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -66,42 +66,6 @@ html.dark {
6666
color: var(--shiki-dark, inherit) !important;
6767
}
6868

69-
/* Splitpanes */
70-
.splitpanes__splitter {
71-
position: relative;
72-
}
73-
.splitpanes__splitter:before {
74-
position: absolute;
75-
left: 0;
76-
top: 0;
77-
transition: .2s ease;
78-
content: '';
79-
transition: opacity 0.4s;
80-
z-index: 1;
81-
}
82-
.splitpanes__splitter:hover:before {
83-
background: #8881;
84-
opacity: 1;
85-
}
86-
.splitpanes--vertical>.splitpanes__splitter {
87-
min-width: 0 !important;
88-
width: 0 !important;
89-
}
90-
.splitpanes--horizontal>.splitpanes__splitter {
91-
min-height: 0 !important;
92-
height: 0 !important;
93-
}
94-
.splitpanes--vertical>.splitpanes__splitter:before {
95-
left: -5px;
96-
right: -4px;
97-
height: 100%;
98-
}
99-
.splitpanes--horizontal>.splitpanes__splitter:before {
100-
top: -5px;
101-
bottom: -4px;
102-
width: 100%;
103-
}
104-
10569
/* JSON Editor */
10670
textarea {
10771
background: #8881

0 commit comments

Comments
 (0)