Skip to content

Commit 8905ba7

Browse files
committed
perf: island mod
1 parent ed5aa19 commit 8905ba7

14 files changed

Lines changed: 429 additions & 74 deletions

File tree

‎i18n/locales/en.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,8 @@
941941
"PrimaryColorDescription": "Used for buttons, selections, and emphasized information.",
942942
"WorkspaceAppearance": "Workspace appearance",
943943
"WorkspaceAppearanceDescription": "Adjust how interface text, command terminals, and text editors are displayed.",
944+
"ModernIsland": "Modern island",
945+
"ModernIslandDescription": "Split the asset tree, session area, and right panel into separate islands with a splitter and accordion.",
944946
"InterfaceFont": "Interface font",
945947
"InterfaceFontDescription": "Font used by menus, navigation, and content areas.",
946948
"InterfaceFontSize": "UI font size",

‎i18n/locales/zh.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,8 @@
944944
"PrimaryColorDescription": "用于按钮、选中状态和重点信息。",
945945
"WorkspaceAppearance": "工作区外观",
946946
"WorkspaceAppearanceDescription": "调整界面文字、命令终端和文本编辑区域的显示效果。",
947+
"ModernIsland": "现代分割",
948+
"ModernIslandDescription": "将左侧资产树、中间会话区和右侧面板拆成独立岛区,使用可拖拽分割与折叠手风琴。",
947949
"InterfaceFont": "界面字体",
948950
"InterfaceFontDescription": "应用菜单、导航和内容区域使用的字体。",
949951
"InterfaceFontSize": "UI 字号",

‎ui/assets/css/main.css‎

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@
145145
);
146146
--workspace-surface-sub-tree: color-mix(in srgb, var(--app-surface-panel-strong) 68%, var(--app-surface-canvas) 32%);
147147
--workspace-surface-sub-border: color-mix(in srgb, var(--app-border-subtle) 86%, var(--app-surface-panel) 14%);
148+
--workspace-island-inset: 6px;
149+
--workspace-island-gap: 8px;
150+
--workspace-island-radius: 10px;
151+
--workspace-island-border: color-mix(in srgb, var(--theme-fg) 12%, transparent);
148152
--ui-bg: var(--app-surface-canvas);
149153
--ui-bg-muted: var(--app-surface-sidebar);
150154
--ui-bg-elevated: var(--app-surface-panel);
@@ -452,3 +456,91 @@ option {
452456
flex-shrink: 0;
453457
object-fit: contain;
454458
}
459+
460+
.workspace-shell[data-island] .workspace-shell__header,
461+
.workspace-shell[data-island] .header-bg {
462+
background-color: var(--app-surface-frame);
463+
border-bottom-color: transparent;
464+
}
465+
466+
.workspace-shell[data-island] .workspace-shell__footer {
467+
background-color: var(--app-surface-frame);
468+
}
469+
470+
.workspace-shell__body--island {
471+
padding-top: 0;
472+
padding-right: var(--workspace-island-inset);
473+
padding-bottom: var(--workspace-island-inset);
474+
padding-left: var(--workspace-island-inset);
475+
background-color: var(--app-surface-frame);
476+
}
477+
478+
.workspace-island {
479+
display: flex;
480+
width: 100%;
481+
min-width: 0;
482+
min-height: 0;
483+
height: 100%;
484+
flex: 1 1 auto;
485+
flex-direction: column;
486+
overflow: hidden;
487+
border: 1px solid var(--workspace-island-border);
488+
border-top-width: 0;
489+
border-radius: 0 0 var(--workspace-island-radius) var(--workspace-island-radius);
490+
background-color: var(--app-surface-sidebar);
491+
}
492+
493+
.workspace-island--main {
494+
background-color: var(--app-surface-canvas);
495+
}
496+
497+
.workspace-island--right {
498+
background-color: var(--app-surface-panel);
499+
}
500+
501+
.workspace-island-accordion {
502+
display: flex;
503+
min-height: 0;
504+
flex: 1;
505+
flex-direction: column;
506+
}
507+
508+
.workspace-island-accordion [data-slot="item"] {
509+
display: flex;
510+
min-height: 32px;
511+
flex-direction: column;
512+
}
513+
514+
.workspace-island-accordion [data-slot="item"][data-state="open"][data-value="assets"] {
515+
min-height: 140px;
516+
flex: 1 1 auto;
517+
}
518+
519+
.workspace-island-accordion [data-slot="item"][data-state="open"]:not([data-value="assets"]) {
520+
max-height: 38%;
521+
flex: 0 1 auto;
522+
}
523+
524+
.workspace-island-accordion [data-slot="content"] {
525+
min-height: 0;
526+
flex: 1;
527+
overflow: hidden;
528+
}
529+
530+
.workspace-shell[data-island] .workspace-shell__sidebar {
531+
background-color: transparent;
532+
border-right-width: 0;
533+
}
534+
535+
.workspace-shell[data-island] .workspace-shell__right-panel {
536+
background-color: transparent;
537+
}
538+
539+
.workspace-island--sidebar > * {
540+
border-right-width: 0;
541+
background-color: transparent;
542+
}
543+
544+
.workspace-island--right > * {
545+
border-left-width: 0;
546+
}

‎ui/components/RightPanel/rightPanel.vue‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { RightPanelTab } from "~/composables/useRightPanel";
33
import { getLionWorkspaceSession } from "@/lion/workspaces/useLionWorkspaceSessionRegistry";
44
55
const { t } = useI18n();
6+
const { modernIsland } = useSettingManager();
67
const { activePaneId, activeTab: workspaceTab } = useWorkspaceTabs();
78
const { activeWorkspaceMode } = useWorkspaceMode();
89
const { activeTab, setActiveTab, setOpen } = useRightPanel();
@@ -77,8 +78,8 @@ watch(
7778
<aside
7879
class="flex h-full min-h-0 w-full flex-col"
7980
:style="{
80-
borderLeft: '1px solid var(--app-border)',
81-
backgroundColor: 'var(--app-panel-bg)',
81+
borderLeft: modernIsland ? '0' : '1px solid var(--app-border)',
82+
backgroundColor: modernIsland ? 'transparent' : 'var(--app-panel-bg)',
8283
color: 'var(--app-fg)'
8384
}"
8485
>

‎ui/components/SideBar/assetTree.vue‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useUserInfoStore } from "~/store/modules/userInfo";
66
const props = defineProps<{
77
search: string;
88
open?: boolean;
9+
hideHeader?: boolean;
910
}>();
1011
1112
const emit = defineEmits<{
@@ -456,7 +457,7 @@ defineExpose({ refresh, loading });
456457
<template>
457458
<div
458459
class="flex min-h-8 flex-col"
459-
:class="open === false ? 'h-8 shrink-0' : 'min-h-0 flex-1'"
460+
:class="open === false && !hideHeader ? 'h-8 shrink-0' : 'min-h-0 flex-1'"
460461
role="tree"
461462
:aria-label="t('Menu.Resource')"
462463
:data-workspace-tour="search.trim() ? undefined : 'assets'"
@@ -505,6 +506,7 @@ defineExpose({ refresh, loading });
505506
class="flex h-8 w-full shrink-0 items-center gap-1 px-2.5 text-xs font-medium text-gray-700 dark:text-gray-300"
506507
>
507508
<button
509+
v-if="!hideHeader"
508510
type="button"
509511
class="flex min-w-0 flex-1 cursor-pointer items-center gap-1.5 text-left"
510512
:aria-expanded="open !== false"
@@ -517,6 +519,7 @@ defineExpose({ refresh, loading });
517519
/>
518520
<span class="min-w-0 flex-1 truncate">{{ activeTree.label }}</span>
519521
</button>
522+
<div v-else class="min-w-0 flex-1" />
520523
<div v-if="batchMode" class="flex items-center gap-1 text-[11px] text-gray-500 dark:text-gray-400">
521524
<span class="hidden sm:inline">{{ t("Tree.SelectedCount", { count: checkedCount }) }}</span>
522525
<UButton
@@ -586,7 +589,7 @@ defineExpose({ refresh, loading });
586589
</div>
587590
</div>
588591

589-
<div v-if="open !== false" class="min-h-0 flex-1 overflow-y-auto py-0">
592+
<div v-if="hideHeader || open !== false" class="min-h-0 flex-1 overflow-y-auto py-0">
590593
<div v-if="loading && activeTree.nodes.length === 0" class="grid h-20 place-items-center">
591594
<UIcon name="i-lucide-loader-circle" class="sidebar-icon animate-spin" />
592595
</div>

‎ui/components/SideBar/bottomPanels.vue‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const props = defineProps<{
1111
favorites: boolean;
1212
snippets: boolean;
1313
};
14+
hideChrome?: boolean;
1415
}>();
1516
1617
const emit = defineEmits<{
@@ -449,11 +450,12 @@ const folderMenuItems = computed<DropdownMenuItem[]>(() => {
449450
<div class="contents">
450451
<SideBarCollapsiblePanel
451452
v-if="visiblePanels.favorites"
452-
:open="isOpen('favorites')"
453+
:open="hideChrome || isOpen('favorites')"
453454
:title="t('Menu.Favorite')"
454455
v-bind="panelConfig.favorites"
455456
:max-height="panelMaxHeight('favorites')"
456457
:fill-available="!mainPanelOpen"
458+
:hide-chrome="hideChrome"
457459
@toggle="togglePanel('favorites')"
458460
>
459461
<template #actions>
@@ -514,11 +516,12 @@ const folderMenuItems = computed<DropdownMenuItem[]>(() => {
514516

515517
<SideBarCollapsiblePanel
516518
v-if="visiblePanels.snippets"
517-
:open="isOpen('snippets')"
519+
:open="hideChrome || isOpen('snippets')"
518520
:title="t('Menu.Snippets')"
519521
v-bind="panelConfig.snippets"
520522
:max-height="panelMaxHeight('snippets')"
521523
:fill-available="!mainPanelOpen"
524+
:hide-chrome="hideChrome"
522525
@toggle="togglePanel('snippets')"
523526
>
524527
<template #actions>

‎ui/components/SideBar/collapsiblePanel.vue‎

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,30 @@ const props = withDefaults(
99
minHeight?: number;
1010
maxHeight?: string;
1111
fillAvailable?: boolean;
12+
hideChrome?: boolean;
1213
}>(),
1314
{
1415
preferredHeight: 200,
1516
minHeight: 112,
16-
maxHeight: "50%"
17+
maxHeight: "50%",
18+
hideChrome: false
1719
}
1820
);
1921
2022
const emit = defineEmits<{
2123
toggle: [];
2224
}>();
2325
24-
const panelStyle = computed(() =>
25-
props.open
26+
const panelStyle = computed(() => {
27+
if (props.hideChrome) {
28+
return {
29+
height: "auto",
30+
minHeight: 0,
31+
flexGrow: 1
32+
};
33+
}
34+
35+
return props.open
2636
? props.fillAvailable
2737
? {
2838
height: "auto",
@@ -33,16 +43,18 @@ const panelStyle = computed(() =>
3343
height: `min(${props.preferredHeight}px, ${props.maxHeight})`,
3444
minHeight: `min(${props.minHeight}px, ${props.maxHeight})`
3545
}
36-
: { height: "32px" }
37-
);
46+
: { height: "32px" };
47+
});
3848
</script>
3949

4050
<template>
4151
<section
42-
class="group flex min-h-8 shrink-0 flex-col overflow-hidden border-t border-gray-200 dark:border-white/10"
52+
class="group flex flex-col overflow-hidden"
53+
:class="hideChrome ? 'min-h-0 flex-1' : 'min-h-8 shrink-0 border-t border-gray-200 dark:border-white/10'"
4354
:style="panelStyle"
4455
>
4556
<button
57+
v-if="!hideChrome"
4658
type="button"
4759
class="flex h-8 shrink-0 cursor-pointer items-center gap-1.5 px-2.5 text-left text-xs font-medium text-gray-700 dark:text-gray-200"
4860
:aria-expanded="open"
@@ -59,7 +71,7 @@ const panelStyle = computed(() =>
5971
</div>
6072
</button>
6173

62-
<div v-if="open" class="min-h-0 flex-1 overflow-y-auto">
74+
<div v-if="open || hideChrome" class="min-h-0 flex-1 overflow-y-auto">
6375
<slot />
6476
</div>
6577
</section>

0 commit comments

Comments
 (0)