diff --git a/src/components/dockview.tsx b/src/components/dockview.tsx new file mode 100644 index 0000000..87f75df --- /dev/null +++ b/src/components/dockview.tsx @@ -0,0 +1,150 @@ +"use client"; + +import { + DockviewReact, + themeAbyssSpaced, + type DockviewReadyEvent, + type IDockviewPanelHeaderProps, +} from "dockview"; +import { + CircleCheckBigIcon, + FileTextIcon, + FlaskConicalIcon, + type LucideProps, + SquareCheckIcon, + SquarePenIcon, + TerminalIcon +} from "lucide-react"; +import "@/styles/dockview.css"; +import { type ForwardRefExoticComponent, type RefAttributes, useMemo } from "react"; + +interface DockviewProps { + Description: React.ReactNode; + Solutions: React.ReactNode; + Submissions: React.ReactNode; + Code: React.ReactNode; + Testcase: React.ReactNode; + TestResult: React.ReactNode; +} + +const PanelIcons: Record & RefAttributes>> = { + Description: FileTextIcon, + Solutions: FlaskConicalIcon, + Submissions: CircleCheckBigIcon, + Code: SquarePenIcon, + Testcase: SquareCheckIcon, + TestResult: TerminalIcon, +}; + +const LAYOUT_STORAGE_KEY = "dockview:layout"; + +const DefaultTab = ({ params }: IDockviewPanelHeaderProps<{ title: string }>) => { + const { title } = params; + const Icon = PanelIcons[title]; + + return ( +
+ {Icon && ( +
+ ); +}; + +const tabComponents = { + default: DefaultTab, +}; + +const DEFAULT_PANELS = [ + { id: "Description", component: "Description", position: null }, + { + id: "Solutions", + component: "Solutions", + position: { referencePanel: "Description", direction: "within" }, + }, + { + id: "Submissions", + component: "Submissions", + position: { referencePanel: "Solutions", direction: "within" }, + }, + { + id: "Code", + component: "Code", + position: { referencePanel: "Submissions", direction: "right" }, + }, + { + id: "Testcase", + component: "Testcase", + position: { referencePanel: "Code", direction: "below" }, + }, + { + id: "TestResult", + component: "TestResult", + position: { referencePanel: "Testcase", direction: "within" }, + }, +]; + +export default function DockView(props: DockviewProps) { + const components = useMemo( + () => ({ + Description: () => props.Description, + Solutions: () => props.Solutions, + Submissions: () => props.Submissions, + Code: () => props.Code, + Testcase: () => props.Testcase, + TestResult: () => props.TestResult, + }), + [props] + ); + + const handleReady = (event: DockviewReadyEvent) => { + let success = false; + + try { + const layout = localStorage.getItem(LAYOUT_STORAGE_KEY); + if (layout) { + event.api.fromJSON(JSON.parse(layout)); + success = true; + } + } catch (error) { + console.error("Failed to load layout:", error); + localStorage.removeItem(LAYOUT_STORAGE_KEY); + } + + if (!success) { + DEFAULT_PANELS.forEach(({ id, component, position }) => { + event.api.addPanel({ + id, + component, + tabComponent: "default", + params: { title: id }, + position: position || undefined, + }); + }); + } + + const saveLayout = () => { + localStorage.setItem( + LAYOUT_STORAGE_KEY, + JSON.stringify(event.api.toJSON()) + ); + }; + + const disposable = event.api.onDidLayoutChange(saveLayout); + return () => disposable.dispose(); + }; + + return ( + + ); +} diff --git a/src/styles/dockview.css b/src/styles/dockview.css new file mode 100644 index 0000000..c20c886 --- /dev/null +++ b/src/styles/dockview.css @@ -0,0 +1,860 @@ +.dv-scrollable { + position: relative; + overflow: hidden; +} + +.dv-scrollable .dv-scrollbar-horizontal { + position: absolute; + bottom: 0px; + left: 0px; + height: 4px; + border-radius: 2px; + background-color: transparent; + transition-property: background-color; + transition-timing-function: ease-in-out; + transition-duration: 1s; + transition-delay: 0s; +} + +.dv-scrollable:hover .dv-scrollbar-horizontal, +.dv-scrollable.dv-scrollable-resizing .dv-scrollbar-horizontal, +.dv-scrollable.dv-scrollable-scrolling .dv-scrollbar-horizontal { + background-color: var(--dv-scrollbar-background-color, rgba(255, 255, 255, 0.25)); +} + +.dv-svg { + display: inline-block; + fill: currentcolor; + line-height: 1; + stroke: currentcolor; + stroke-width: 0; +} + +.dockview-theme-abyss-spaced { + --dv-paneview-active-outline-color: dodgerblue; + --dv-tabs-and-actions-container-font-size: 13px; + --dv-tabs-and-actions-container-height: 35px; + --dv-drag-over-background-color: hsl(var(--accent) / 50%); + --dv-drag-over-border-color: transparent; + --dv-tabs-container-scrollbar-color: #888; + --dv-icon-hover-background-color: rgba(90, 93, 94, 0.31); + --dv-floating-box-shadow: 8px 8px 8px 0px rgba(83, 89, 93, 0.5); + --dv-overlay-z-index: 999; + --dv-tab-font-size: inherit; + --dv-border-radius: 0px; + --dv-tab-margin: 0; + --dv-sash-color: transparent; + --dv-active-sash-color: transparent; + --dv-active-sash-transition-duration: 0.1s; + --dv-active-sash-transition-delay: 0.5s; + --dv-tab-font-size: 12px; + --dv-border-radius: 20px; + --dv-tab-margin: 0.5rem 0.25rem; + --dv-tabs-and-actions-container-height: 44px; + --dv-border-radius: 20px; + --dv-color-abyss-dark: hsl(var(--background)); + --dv-color-abyss: hsl(var(--muted)); + --dv-color-abyss-light: hsl(var(--muted)); + --dv-color-abyss-lighter: hsl(var(--background)); + --dv-color-abyss-accent: rgb(59, 130, 246); + --dv-color-abyss-primary-text: hsl(var(--muted-foreground)); + --dv-color-abyss-secondary-text: hsl(var(--muted-foreground)); + --dv-drag-over-border: 2px solid var(--dv-color-abyss-accent); + --dv-group-view-background-color: var(--dv-color-abyss-dark); + --dv-tabs-and-actions-container-background-color: var(--dv-color-abyss); + --dv-activegroup-visiblepanel-tab-background-color: var(--dv-color-abyss-lighter); + --dv-activegroup-hiddenpanel-tab-background-color: var(--dv-color-abyss-light); + --dv-inactivegroup-visiblepanel-tab-background-color: var(--dv-color-abyss-lighter); + --dv-inactivegroup-hiddenpanel-tab-background-color: var(--dv-color-abyss-light); + --dv-tab-divider-color: transparent; + --dv-activegroup-visiblepanel-tab-color: var(--dv-color-abyss-primary-text); + --dv-activegroup-hiddenpanel-tab-color: var(--dv-color-abyss-secondary-text); + --dv-inactivegroup-visiblepanel-tab-color: var(--dv-color-abyss-primary-text); + --dv-inactivegroup-hiddenpanel-tab-color: var(--dv-color-abyss-secondary-text); + --dv-separator-border: transparent; + --dv-paneview-header-border-color: rgb(51, 51, 51); + --dv-active-sash-color: var(--dv-color-abyss-accent); + --dv-floating-box-shadow: 8px 8px 8px 0px rgba(0, 0, 0, 0.5); + background-color: var(--dv-color-abyss-dark); +} + +.dockview-theme-abyss-spaced .dv-resize-container:has(> .dv-groupview) { + border-radius: 8px; +} + +.dockview-theme-abyss-spaced .dv-sash { + border-radius: 4px; +} + +.dockview-theme-abyss-spaced .dv-drop-target-anchor { + border-radius: calc(var(--dv-border-radius) / 4); +} + +.dockview-theme-abyss-spaced .dv-drop-target-anchor.dv-drop-target-content { + border-radius: var(--dv-border-radius); +} + +.dockview-theme-abyss-spaced .dv-resize-container { + border-radius: var(--dv-border-radius) !important; + border: none; +} + +.dockview-theme-abyss-spaced .dv-tabs-overflow-container, +.dockview-theme-abyss-spaced .dv-tabs-overflow-dropdown-default { + border-radius: 8px; + height: unset !important; +} + +.dockview-theme-abyss-spaced .dv-tab { + border-radius: 8px; +} + +.dockview-theme-abyss-spaced .dv-tab .dv-svg { + height: 8px; + width: 8px; +} + +.dockview-theme-abyss-spaced .dv-groupview { + border-radius: var(--dv-border-radius); +} + +.dockview-theme-abyss-spaced .dv-groupview .dv-tabs-and-actions-container { + padding: 0px calc(var(--dv-border-radius) / 2); +} + +.dockview-theme-abyss-spaced .dv-groupview .dv-content-container { + background-color: var(--dv-tabs-and-actions-container-background-color); +} + +.dockview-theme-abyss-spaced .dv-resize-container .dv-groupview { + border: 2px solid var(--dv-color-abyss-dark); +} + +.dv-drop-target-container { + position: absolute; + z-index: 9999; + top: 0px; + left: 0px; + height: 100%; + width: 100%; + pointer-events: none; + overflow: hidden; + --dv-transition-duration: 300ms; +} + +.dv-drop-target-container .dv-drop-target-anchor { + position: relative; + border: var(--dv-drag-over-border); + transition: opacity var(--dv-transition-duration) ease-in, top var(--dv-transition-duration) ease-out, left var(--dv-transition-duration) ease-out, width var(--dv-transition-duration) ease-out, height var(--dv-transition-duration) ease-out; + background-color: var(--dv-drag-over-background-color); + opacity: 1; +} + +.dv-drop-target { + position: relative; + --dv-transition-duration: 70ms; +} + +.dv-drop-target>.dv-drop-target-dropzone { + position: absolute; + left: 0px; + top: 0px; + height: 100%; + width: 100%; + z-index: 1000; + pointer-events: none; +} + +.dv-drop-target>.dv-drop-target-dropzone>.dv-drop-target-selection { + position: relative; + box-sizing: border-box; + height: 100%; + width: 100%; + border: var(--dv-drag-over-border); + background-color: var(--dv-drag-over-background-color); + transition: top var(--dv-transition-duration) ease-out, left var(--dv-transition-duration) ease-out, width var(--dv-transition-duration) ease-out, height var(--dv-transition-duration) ease-out, opacity var(--dv-transition-duration) ease-out; + will-change: transform; + pointer-events: none; +} + +.dv-drop-target>.dv-drop-target-dropzone>.dv-drop-target-selection.dv-drop-target-top.dv-drop-target-small-vertical { + border-top: 1px solid var(--dv-drag-over-border-color); +} + +.dv-drop-target>.dv-drop-target-dropzone>.dv-drop-target-selection.dv-drop-target-bottom.dv-drop-target-small-vertical { + border-bottom: 1px solid var(--dv-drag-over-border-color); +} + +.dv-drop-target>.dv-drop-target-dropzone>.dv-drop-target-selection.dv-drop-target-left.dv-drop-target-small-horizontal { + border-left: 1px solid var(--dv-drag-over-border-color); +} + +.dv-drop-target>.dv-drop-target-dropzone>.dv-drop-target-selection.dv-drop-target-right.dv-drop-target-small-horizontal { + border-right: 1px solid var(--dv-drag-over-border-color); +} + +.dv-dockview { + position: relative; + background-color: var(--dv-group-view-background-color); +} + +.dv-dockview .dv-watermark-container { + position: absolute; + top: 0px; + left: 0px; + height: 100%; + width: 100%; + z-index: 1; +} + +.dv-dockview .dv-overlay-render-container { + position: relative; +} + +.dv-groupview.dv-active-group>.dv-tabs-and-actions-container .dv-tabs-container>.dv-tab.dv-active-tab { + background-color: var(--dv-activegroup-visiblepanel-tab-background-color); + color: var(--dv-activegroup-visiblepanel-tab-color); +} + +.dv-groupview.dv-active-group>.dv-tabs-and-actions-container .dv-tabs-container>.dv-tab.dv-inactive-tab { + background-color: var(--dv-activegroup-hiddenpanel-tab-background-color); + color: var(--dv-activegroup-hiddenpanel-tab-color); +} + +.dv-groupview.dv-inactive-group>.dv-tabs-and-actions-container .dv-tabs-container>.dv-tab.dv-active-tab { + background-color: var(--dv-inactivegroup-visiblepanel-tab-background-color); + color: var(--dv-inactivegroup-visiblepanel-tab-color); +} + +.dv-groupview.dv-inactive-group>.dv-tabs-and-actions-container .dv-tabs-container>.dv-tab.dv-inactive-tab { + background-color: var(--dv-inactivegroup-hiddenpanel-tab-background-color); + color: var(--dv-inactivegroup-hiddenpanel-tab-color); +} + +/** + * when a tab is dragged we lose the above stylings because they are conditional on parent elements + * therefore we also set some stylings for the dragging event + **/ +.dv-tab.dv-tab-dragging { + background-color: var(--dv-activegroup-visiblepanel-tab-background-color); + color: var(--dv-activegroup-visiblepanel-tab-color); +} + +.dv-groupview { + display: flex; + flex-direction: column; + height: 100%; + background-color: var(--dv-group-view-background-color); + overflow: hidden; +} + +.dv-groupview:focus { + outline: none; +} + +.dv-groupview>.dv-content-container { + flex-grow: 1; + min-height: 0; + outline: none; +} + +.dv-root-wrapper { + height: 100%; + width: 100%; +} + +.dv-grid-view, +.dv-branch-node { + height: 100%; + width: 100%; +} + +.dv-debug .dv-resize-container .dv-resize-handle-top { + background-color: red; +} + +.dv-debug .dv-resize-container .dv-resize-handle-bottom { + background-color: green; +} + +.dv-debug .dv-resize-container .dv-resize-handle-left { + background-color: yellow; +} + +.dv-debug .dv-resize-container .dv-resize-handle-right { + background-color: blue; +} + +.dv-debug .dv-resize-container .dv-resize-handle-topleft, +.dv-debug .dv-resize-container .dv-resize-handle-topright, +.dv-debug .dv-resize-container .dv-resize-handle-bottomleft, +.dv-debug .dv-resize-container .dv-resize-handle-bottomright { + background-color: cyan; +} + +.dv-resize-container { + --dv-overlay-z-index: var(--dv-overlay-z-index, 999); + position: absolute; + z-index: calc(var(--dv-overlay-z-index) - 2); + border: 1px solid var(--dv-tab-divider-color); + box-shadow: var(--dv-floating-box-shadow); +} + +.dv-resize-container.dv-hidden { + display: none; +} + +.dv-resize-container.dv-resize-container-dragging { + opacity: 0.5; +} + +.dv-resize-container .dv-resize-handle-top { + height: 4px; + width: calc(100% - 8px); + left: 4px; + top: -2px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: ns-resize; +} + +.dv-resize-container .dv-resize-handle-bottom { + height: 4px; + width: calc(100% - 8px); + left: 4px; + bottom: -2px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: ns-resize; +} + +.dv-resize-container .dv-resize-handle-left { + height: calc(100% - 8px); + width: 4px; + left: -2px; + top: 4px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: ew-resize; +} + +.dv-resize-container .dv-resize-handle-right { + height: calc(100% - 8px); + width: 4px; + right: -2px; + top: 4px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: ew-resize; +} + +.dv-resize-container .dv-resize-handle-topleft { + height: 4px; + width: 4px; + top: -2px; + left: -2px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: nw-resize; +} + +.dv-resize-container .dv-resize-handle-topright { + height: 4px; + width: 4px; + right: -2px; + top: -2px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: ne-resize; +} + +.dv-resize-container .dv-resize-handle-bottomleft { + height: 4px; + width: 4px; + left: -2px; + bottom: -2px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: sw-resize; +} + +.dv-resize-container .dv-resize-handle-bottomright { + height: 4px; + width: 4px; + right: -2px; + bottom: -2px; + z-index: var(--dv-overlay-z-index); + position: absolute; + cursor: se-resize; +} + +.dv-render-overlay { + --dv-overlay-z-index: var(--dv-overlay-z-index, 999); + position: absolute; + z-index: 1; + height: 100%; +} + +.dv-render-overlay.dv-render-overlay-float { + z-index: calc(var(--dv-overlay-z-index) - 1); +} + +.dv-debug .dv-render-overlay { + outline: 1px solid red; + outline-offset: -1; +} + +.dv-pane-container { + height: 100%; + width: 100%; +} + +.dv-pane-container.dv-animated .dv-view { + transition-duration: 0.15s; + transition-timing-function: ease-out; +} + +.dv-pane-container .dv-view { + overflow: hidden; + display: flex; + flex-direction: column; + padding: 0px !important; +} + +.dv-pane-container .dv-view:not(:first-child)::before { + background-color: transparent !important; +} + +.dv-pane-container .dv-view:not(:first-child) .dv-pane>.dv-pane-header { + border-top: 1px solid var(--dv-paneview-header-border-color); +} + +.dv-pane-container .dv-view .dv-default-header { + background-color: var(--dv-group-view-background-color); + color: var(--dv-activegroup-visiblepanel-tab-color); + display: flex; + padding: 0px 8px; + cursor: pointer; +} + +.dv-pane-container .dv-view .dv-default-header .dv-pane-header-icon { + display: flex; + justify-content: center; + align-items: center; +} + +.dv-pane-container .dv-view .dv-default-header>span { + padding-left: 8px; + flex-grow: 1; +} + +.dv-pane-container:first-of-type>.dv-pane>.dv-pane-header { + border-top: none !important; +} + +.dv-pane-container .dv-pane { + display: flex; + flex-direction: column; + overflow: hidden; + height: 100%; +} + +.dv-pane-container .dv-pane .dv-pane-header { + box-sizing: border-box; + user-select: none; + position: relative; + outline: none; +} + +.dv-pane-container .dv-pane .dv-pane-header.dv-pane-draggable { + cursor: pointer; +} + +.dv-pane-container .dv-pane .dv-pane-header:focus:before, +.dv-pane-container .dv-pane .dv-pane-header:focus-within:before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 5; + content: ""; + pointer-events: none; + outline: 1px solid; + outline-width: -1px; + outline-style: solid; + outline-offset: -1px; + outline-color: var(--dv-paneview-active-outline-color); +} + +.dv-pane-container .dv-pane .dv-pane-body { + overflow-y: auto; + overflow-x: hidden; + flex-grow: 1; + position: relative; + outline: none; +} + +.dv-pane-container .dv-pane .dv-pane-body:focus:before, +.dv-pane-container .dv-pane .dv-pane-body:focus-within:before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 5; + content: ""; + pointer-events: none; + outline: 1px solid; + outline-width: -1px; + outline-style: solid; + outline-offset: -1px; + outline-color: var(--dv-paneview-active-outline-color); +} + +.dv-debug .dv-split-view-container .dv-sash-container .dv-sash.dv-enabled { + background-color: black; +} + +.dv-debug .dv-split-view-container .dv-sash-container .dv-sash.dv-disabled { + background-color: orange; +} + +.dv-debug .dv-split-view-container .dv-sash-container .dv-sash.dv-maximum { + background-color: green; +} + +.dv-debug .dv-split-view-container .dv-sash-container .dv-sash.dv-minimum { + background-color: red; +} + +.dv-split-view-container { + position: relative; + overflow: hidden; + height: 100%; + width: 100%; +} + +.dv-split-view-container.dv-splitview-disabled>.dv-sash-container>.dv-sash { + pointer-events: none; +} + +.dv-split-view-container.dv-animation .dv-view, +.dv-split-view-container.dv-animation .dv-sash { + transition-duration: 0.15s; + transition-timing-function: ease-out; +} + +.dv-split-view-container.dv-horizontal { + height: 100%; +} + +.dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash { + height: 100%; + width: 4px; +} + +.dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash.dv-enabled { + cursor: ew-resize; +} + +.dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash.dv-disabled { + cursor: default; +} + +.dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash.dv-maximum { + cursor: w-resize; +} + +.dv-split-view-container.dv-horizontal>.dv-sash-container>.dv-sash.dv-minimum { + cursor: e-resize; +} + +.dv-split-view-container.dv-horizontal>.dv-view-container>.dv-view:not(:first-child)::before { + height: 100%; + width: 1px; +} + +.dv-split-view-container.dv-vertical { + width: 100%; +} + +.dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash { + width: 100%; + height: 4px; +} + +.dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash.dv-enabled { + cursor: ns-resize; +} + +.dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash.dv-disabled { + cursor: default; +} + +.dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash.dv-maximum { + cursor: n-resize; +} + +.dv-split-view-container.dv-vertical>.dv-sash-container>.dv-sash.dv-minimum { + cursor: s-resize; +} + +.dv-split-view-container.dv-vertical>.dv-view-container>.dv-view { + width: 100%; +} + +.dv-split-view-container.dv-vertical>.dv-view-container>.dv-view:not(:first-child)::before { + height: 1px; + width: 100%; +} + +.dv-split-view-container .dv-sash-container { + height: 100%; + width: 100%; + position: absolute; +} + +.dv-split-view-container .dv-sash-container .dv-sash { + position: absolute; + z-index: 99; + outline: none; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + touch-action: none; + background-color: var(--dv-sash-color, transparent); +} + +.dv-split-view-container .dv-sash-container .dv-sash:not(.disabled):active, +.dv-split-view-container .dv-sash-container .dv-sash:not(.disabled):hover { + background-color: var(--dv-active-sash-color, transparent); + transition-property: background-color; + transition-timing-function: ease-in-out; + transition-duration: var(--dv-active-sash-transition-duration, 0.1s); + transition-delay: var(--dv-active-sash-transition-delay, 0.5s); +} + +.dv-split-view-container .dv-view-container { + position: relative; + height: 100%; + width: 100%; +} + +.dv-split-view-container .dv-view-container .dv-view { + height: 100%; + box-sizing: border-box; + overflow: auto; + position: absolute; +} + +.dv-split-view-container.dv-separator-border .dv-view:not(:first-child)::before { + content: " "; + position: absolute; + top: 0; + left: 0; + z-index: 5; + pointer-events: none; + background-color: var(--dv-separator-border); +} + +.dv-dragged { + transform: translate3d(0px, 0px, 0px); + /* forces tab to be drawn on a separate layer (see https://github.com/microsoft/vscode/issues/18733) */ +} + +.dv-tab { + flex-shrink: 0; +} + +.dv-tab:focus-within, +.dv-tab:focus { + position: relative; +} + +.dv-tab:focus-within::after, +.dv-tab:focus::after { + position: absolute; + content: ""; + height: 100%; + width: 100%; + top: 0px; + left: 0px; + pointer-events: none; + outline: 1px solid var(--dv-tab-divider-color) !important; + outline-offset: -1px; + z-index: 5; +} + +.dv-tab.dv-tab-dragging .dv-default-tab-action { + background-color: var(--dv-activegroup-visiblepanel-tab-color); +} + +.dv-tab.dv-active-tab .dv-default-tab .dv-default-tab-action { + visibility: visible; +} + +.dv-tab.dv-inactive-tab .dv-default-tab .dv-default-tab-action { + visibility: hidden; +} + +.dv-tab.dv-inactive-tab .dv-default-tab:hover .dv-default-tab-action { + visibility: visible; +} + +.dv-tab .dv-default-tab { + position: relative; + height: 100%; + display: flex; + align-items: center; + white-space: nowrap; + text-overflow: ellipsis; +} + +.dv-tab .dv-default-tab .dv-default-tab-content { + flex-grow: 1; + margin-right: 4px; +} + +.dv-tab .dv-default-tab .dv-default-tab-action { + padding: 4px; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; +} + +.dv-tab .dv-default-tab .dv-default-tab-action:hover { + border-radius: 2px; + background-color: var(--dv-icon-hover-background-color); +} + +.dv-tabs-overflow-dropdown-default { + height: 100%; + color: var(--dv-activegroup-hiddenpanel-tab-color); + margin: var(--dv-tab-margin); + display: flex; + align-items: center; + flex-shrink: 0; + padding: 0.25rem 0.5rem; + cursor: pointer; +} + +.dv-tabs-overflow-dropdown-default>span { + padding-left: 0.25rem; +} + +.dv-tabs-overflow-dropdown-default>svg { + transform: rotate(90deg); +} + +.dv-tabs-container { + display: flex; + height: 100%; + overflow: auto; + scrollbar-width: thin; + /* Track */ + /* Handle */ +} + +.dv-tabs-container.dv-horizontal .dv-tab:not(:first-child)::before { + content: " "; + position: absolute; + top: 0; + left: 0; + z-index: 5; + pointer-events: none; + background-color: var(--dv-tab-divider-color); + width: 1px; + height: 100%; +} + +.dv-tabs-container::-webkit-scrollbar { + height: 3px; +} + +.dv-tabs-container::-webkit-scrollbar-track { + background: transparent; +} + +.dv-tabs-container::-webkit-scrollbar-thumb { + background: var(--dv-tabs-container-scrollbar-color); +} + +.dv-scrollable>.dv-tabs-container { + overflow: hidden; +} + +.dv-tab { + -webkit-user-drag: element; + outline: none; + padding: 0.25rem 0.5rem; + cursor: pointer; + position: relative; + box-sizing: border-box; + font-size: var(--dv-tab-font-size); + margin: var(--dv-tab-margin); +} + +.dv-tabs-overflow-container { + flex-direction: column; + height: unset; + border: 1px solid var(--dv-tab-divider-color); + background-color: var(--dv-group-view-background-color); +} + +.dv-tabs-overflow-container .dv-tab:not(:last-child) { + border-bottom: 1px solid var(--dv-tab-divider-color); +} + +.dv-tabs-overflow-container .dv-active-tab { + background-color: var(--dv-activegroup-visiblepanel-tab-background-color); + color: var(--dv-activegroup-visiblepanel-tab-color); +} + +.dv-tabs-overflow-container .dv-inactive-tab { + background-color: var(--dv-activegroup-hiddenpanel-tab-background-color); + color: var(--dv-activegroup-hiddenpanel-tab-color); +} + +.dv-tabs-and-actions-container { + display: flex; + background-color: var(--dv-tabs-and-actions-container-background-color); + flex-shrink: 0; + box-sizing: border-box; + height: var(--dv-tabs-and-actions-container-height); + font-size: var(--dv-tabs-and-actions-container-font-size); +} + +.dv-tabs-and-actions-container.dv-single-tab.dv-full-width-single-tab .dv-scrollable { + flex-grow: 1; +} + +.dv-tabs-and-actions-container.dv-single-tab.dv-full-width-single-tab .dv-tabs-container { + flex-grow: 1; +} + +.dv-tabs-and-actions-container.dv-single-tab.dv-full-width-single-tab .dv-tabs-container .dv-tab { + flex-grow: 1; + padding: 0px; +} + +.dv-tabs-and-actions-container.dv-single-tab.dv-full-width-single-tab .dv-void-container { + flex-grow: 0; +} + +.dv-tabs-and-actions-container .dv-void-container { + display: flex; + flex-grow: 1; + cursor: grab; +} + +.dv-tabs-and-actions-container .dv-right-actions-container { + display: flex; +} + +.dv-watermark { + display: flex; + height: 100%; +} \ No newline at end of file