Split

Split is a component for creating resizable, adjustable panels with customizable layouts and styles.

Basic

The Split component allows you to create resizable panels with support for horizontal or vertical layouts. Each panel can have customizable sizes, minimum and maximum constraints, and unique styles.

Site Bar
Workspace
The first tool
The second tool
The third tool
List Branches
List Commits
Message Commit
Details Commit

The basic usage of the Split component involves defining a set of panels with customizable properties and specifying the layout direction (horizontal or vertical).

Panel Configuration

The panels prop allows you to define the layout and behavior of the panels within the Split component. Each panel is represented as an object with several properties, providing flexibility to customize size, constraints, and appearance. Below is a detailed explanation of each property, along with examples.

Name

The name property is a unique identifier for the panel. It is required and used to reference the panel in events, resizing operations, and slot definitions.

Text
Options

<template>
  <Split :panels="[
      { name: 'text', size: 50 },
      { name: 'options', size: 50 }
    ]">
    <template #text>
      <div>Text</div>
    </template>
    <template #options>
      <div>Options</div>
    </template>
  </Split>
</template>

In this example:

  • The first panel is identified by name: "panel1".
  • The second panel is identified by name: "panel2".

The name property is also used to bind specific slots for content.

Size

The size property specifies the initial size of the panel. The value can be defined in percentages or pixels, depending on the units prop of the Split component.

It is important that the sum of the size values across all panels equals 100% (when using percentages) or matches the total available width or height (when using pixels). To avoid potential layout issues, it is recommended to leave one panel without a size value. Panels without a size will automatically adjust to fill the remaining space.
Left Panel
Size: 70 %
Right Panel
Size: 30 %
<template>
  <Split :panels="[
       { name: 'left', size: 70 }, // 70% width
       { name: 'right' } // Fills the remaining 30%
     ]" 
     units="percentages">
    <template #left>
      <div>Left Panel</div>
    </template>
    <template #right>
      <div>Right Panel</div>
    </template>
  </Split>
</template>

Example Explanation:

  • The left panel is explicitly set to take 70% of the available space.
  • The right panel automatically adjusts to take the remaining 30% of the space, ensuring the layout remains balanced.

When using pixels for the units prop, the same principle applies. Ensure the sum of size values does not exceed the container's total width or height, and prefer leaving one panel without a size value to let it adjust dynamically.

minSize

The minSize property defines the minimum size that the panel can shrink to during resizing. It is particularly useful for ensuring that a panel does not collapse or become unusable.

If the minSize value is greater than the size value, the panel will start with the minSize as its initial size. This ensures the panel respects its minimum constraints.
Top Panel
Size: 150 px
Bottom Panel
Size: 300 px
<template>
  <Split :panels="[
       { name: 'top', size: 100, minSize: 150 }, // Starts with 150px due to minSize
       { name: 'bottom', size: 300, minSize: 150 }
     ]"
     units="pixels">
    <template #top>
      <div>Top Panel</div>
    </template>
    <template #bottom>
      <div>Bottom Panel</div>
    </template>
  </Split>
</template>

Example Explanation:

  • The top panel has a size of 100 pixels but a minSize of 150 pixels. As a result, it starts with 150 pixels to respect the minimum size constraint.
  • The bottom panel has no minSize specified and can shrink to 0 if necessary.

By properly configuring minSize, you can ensure that panels maintain usability while allowing flexible resizing.

maxSize

The maxSize property sets the maximum size that the panel can expand to during resizing. It ensures that the panel does not grow beyond the specified limit.

Keep in mind the following considerations:
  1. If the sum of size values or maxSize values across all panels exceeds 100% (for percentages) or the total available width or height (for pixels), layout issues may occur.
  2. Ensure that minSize is not greater than maxSize. If this happens, the maxSize will automatically be set to the value of minSize. This avoids conflicting constraints.
  3. Panel size behavior follows this priority: minSize > maxSize > size. This means:
    • minSize always takes precedence.
    • If maxSize and size conflict, maxSize will override size.
Left Panel
Size: 50 %
Right Panel
Size: 50 %
<template>
  <Split :panels="[
       { name: 'left', size: 50, maxSize: 60 }, // Cannot exceed 60%
       { name: 'right', size: 50, minSize: 40, maxSize: 50 } // `maxSize` will equal `minSize` (40%)
     ]"
     units="percentages">
    <template #left>
      <div>Left Panel</div>
    </template>
    <template #right>
      <div>Right Panel</div>
    </template>
  </Split>
</template>

Example Explanation:

  • The left panel starts with 50% width but cannot grow beyond 60%.
  • The right panel has a minSize of 40% and a maxSize of 50%. Since minSize is greater than maxSize, maxSize is adjusted to match minSize (40%). The panel starts at 40% and cannot grow or shrink.

By properly configuring maxSize, you can enforce size constraints while maintaining flexibility. Always ensure that minSize, maxSize, and size are consistent to avoid unexpected behavior.

Disabled

The disabled property disables resizing for the panel. When set to true, the panel cannot be resized, and the separator adjacent to it is inactive.

Resizable Panel
Resizable Panel
Static Panel
Resizable Panel
Resizable Panel
<template>
   <Split 
     class="relative rounded-lg border dark:border-gray-800"
     :styles="{panel: 'h-28 flex justify-center items-center font-semibold text-xl'}" 
     :panels="[
        { name: 'resizable1', },
        { name: 'resizable2', },
        { name: 'static', size: 30, disabled: true }, // Disabled resizing
        { name: 'resizable3' },
        { name: 'resizable4' }
     ]">
      <template #static>
         <div class="m-2">Static Panel</div>
      </template>
      <template #resizable1>
         <div class="m-2">Resizable Panel</div>
      </template>
      ...
   </Split>
</template>

In this example:

  • The static panel is locked at 30% of the container's width and cannot be resized.
  • The resizable panel can be resized freely within its constraints.

Class

The class property allows you to apply a custom CSS class to the panel. This can be useful for applying styles such as background color, padding, or borders.

Styled Panel
Default Panel
<template>
  <Split :panels="[
  { name: 'styled', class: 'custom-panel-class' }, // Custom CSS class applied
  { name: 'default' }
  ]">
    <template #styled>
      <div>Styled Panel</div>
    </template>
    <template #default>
      <div>Default Panel</div>
    </template>
  </Split>
</template>

In this example:

  • The styled panel has a custom background color, padding, and border defined in the custom-panel-class.
  • The default panel uses the default styles.

Custom properties

You can pass additional custom properties for the panel, which can be used to extend functionality or transfer metadata to the panel.

Direction

The direction prop controls the layout direction of the panels. It can be one of the following values:

  • "horizontal": Panels are arranged side-by-side.
  • "vertical": Panels are stacked on top of each other.
vertical
Direction
0 px
0 px
<Split :panels="panels" direction="horizontal"></Split>
<Split :panels="panels" direction="vertical"></Split>

Units

The units prop specifies the measurement units for panel sizes. It can be one of the following values:

  • "percentages": Sizes are defined as percentages of the container (default).
  • "pixels": Sizes are defined in pixels.
50 %
50 %
0 px
0 px
<Split :panels="panels" direction="horizontal" units="percentages"></Split>
<Split :panels="panels" direction="horizontal" units="pixels"></Split>

Separator Opacity

The separatorNotHoverOpacity prop determines whether the separator's opacity reduces when not hovered. It accepts:

  • true: Separator is less visible when not hovered.
  • false: Separator maintains full opacity (default).
<Split :panels="panels" :separatorNotHoverOpacity="true"></Split>
<Split :panels="panels" :separatorNotHoverOpacity="false"></Split>

Separator Type

The separatorType prop defines the appearance of the separator between panels. It can be one of the following values:

  • "strip": A simple strip separator (default).
  • "hexagon": A hexagonal separator.
  • Any other valid icon name from your icon library.
<Split :panels="panels" separatorType="strip"></Split>
<Split :panels="panels" separatorType="hexagon"></Split>
<Split :panels="panels" separatorType="custom-icon"></Split>

Events

Resize Events

The Split component emits several events related to panel resizing:

  • updated-panels: Emitted when panel sizes are updated. Provides an object with the updated sizes.
  • updated-size-panel: Emitted when a single panel's size is updated. Provides the new size and panel name.
  • start-resize-panel: Emitted when resizing starts for a panel.
  • stop-resize-panel: Emitted when resizing stops for a panel.
  • move-resize-panel: Emitted when a panel is actively being resized.
  • out-resize-panel: Emitted when the resize action exits a panel boundary.
Move Panel
Resize Panel
First
50 %
Second
50 %
<Split
  :panels="panels"
  @updated-panels="onUpdatedPanels"
  @updated-size-panel="onUpdatedSizePanel"
  @start-resize-panel="onStartResize"
  @stop-resize-panel="onStopResizePanel"
  @move-resize-panel="onMoveResizePanel"
  @out-resize-panel="onOutResizePanel">
</Split>

This example demonstrates how to listen for resize-related events in the Split component.

Slots

Panel Slots

Each panel in the Split component can have a named slot corresponding to its name property. Use the slot to provide custom content for the panel.

Fisht
Fisht
<template>
  <Split :panels="panels">
    <template #panel1>
      <img class="..." src="/image/name.jpg" alt=""/>
    </template>
    <template #panel2>
      <img class="..." src="/image/name.jpg" alt=""/>
    </template>
  </Split>
</template>
© 2025 FishtVue by Egoka