mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat(components): [splitter] new component (#20145)
* feat(components): [splitter] new component * docs(components): [splitter] update docs * feat(components): [splitter] add export ElSplitter ElSplitterPanel types * feat(components): [splitter] support touch even * Update docs/.vitepress/crowdin/en-US/pages/component.json Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> * docs: update * docs: update * chore: update docs & code * chore: update docs & fix code type error * fix: use slot show error * refactor(components): [splitter] modify props use * refactor(components): [splitter] use native event listener to drag * fix(components): [splitter] panel bind attrs * refactor: use `useOrderedChildren` * chore: fix types * feat: add icon * chore: translate comments and add beta tag * docs: add default-size api * docs: remove demo lang="scss" * refactor: remove default-size api --------- Co-authored-by: kooriookami <38392315+kooriookami@users.noreply.github.com> Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> Co-authored-by: warmthsea <2586244885@qq.com> Co-authored-by: Dsaquel <291874700n@gmail.com> Co-authored-by: kooriookami <bingshuanglingluo@163.com>
This commit is contained in:
@@ -52,6 +52,11 @@
|
||||
"link": "/space",
|
||||
"text": "Space"
|
||||
},
|
||||
{
|
||||
"link": "/splitter",
|
||||
"text": "Splitter",
|
||||
"promotion": "2.10.0"
|
||||
},
|
||||
{
|
||||
"link": "/typography",
|
||||
"text": "Typography"
|
||||
|
||||
@@ -61,6 +61,14 @@
|
||||
>
|
||||
@叨叨
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
:underline="false"
|
||||
href="https://github.com/zhiwendesign"
|
||||
target="_blank"
|
||||
>
|
||||
@卡卡
|
||||
</el-link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -189,7 +197,10 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.designed-by {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ import OvDivider from './ov-divider.vue'
|
||||
import OvWatermark from './ov-watermark.vue'
|
||||
import OvMention from './ov-mention.vue'
|
||||
import OvInputTag from './ov-input-tag.vue'
|
||||
import OvSplitter from './ov-splitter.vue'
|
||||
|
||||
export default {
|
||||
button: OvButton,
|
||||
@@ -139,6 +140,7 @@ export default {
|
||||
menu: OvMenu,
|
||||
'page-header': OvPageHeader,
|
||||
steps: OvSteps,
|
||||
splitter: OvSplitter,
|
||||
tabs: OvTabs,
|
||||
alert: OvAlert,
|
||||
dialog: OvDialog,
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<svg
|
||||
width="280"
|
||||
height="180"
|
||||
viewBox="0 0 280 180"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect width="280" height="180" fill="var(--el-fill-color-light)" />
|
||||
<g clip-path="url(#clip0_2477_1001)">
|
||||
<mask id="path-3-inside-1_2477_1001" fill="white">
|
||||
<path d="M80 56H120V124H80V56Z" />
|
||||
</mask>
|
||||
<path d="M80 56H120V124H80V56Z" fill="var(--el-fill-color-blank)" />
|
||||
<path
|
||||
d="M120 56H119.5V124H120H120.5V56H120Z"
|
||||
fill="#CDD0D6"
|
||||
mask="url(#path-3-inside-1_2477_1001)"
|
||||
/>
|
||||
<mask id="path-5-inside-2_2477_1001" fill="white">
|
||||
<path d="M120 56H160V124H120V56Z" />
|
||||
</mask>
|
||||
<path d="M120 56H160V124H120V56Z" fill="var(--el-fill-color-blank)" />
|
||||
<path
|
||||
d="M160 56H159.5V124H160H160.5V56H160Z"
|
||||
fill="#CDD0D6"
|
||||
mask="url(#path-5-inside-2_2477_1001)"
|
||||
/>
|
||||
<rect
|
||||
width="40"
|
||||
height="68"
|
||||
transform="translate(160 56)"
|
||||
fill="var(--el-color-primary-light-8)"
|
||||
/>
|
||||
<rect
|
||||
x="165"
|
||||
y="63"
|
||||
width="20"
|
||||
height="4"
|
||||
rx="2"
|
||||
fill="var(--el-color-primary)"
|
||||
/>
|
||||
<rect
|
||||
x="165"
|
||||
y="70"
|
||||
width="4"
|
||||
height="4"
|
||||
rx="2"
|
||||
fill="var(--el-color-primary-light-5)"
|
||||
/>
|
||||
<rect
|
||||
x="172"
|
||||
y="70"
|
||||
width="21"
|
||||
height="4"
|
||||
rx="2"
|
||||
fill="var(--el-color-primary-light-5)"
|
||||
/>
|
||||
<rect
|
||||
x="172"
|
||||
y="77"
|
||||
width="21"
|
||||
height="4"
|
||||
rx="2"
|
||||
fill="var(--el-color-primary-light-5)"
|
||||
/>
|
||||
<path
|
||||
d="M159.75 83.3335V96.6668"
|
||||
stroke="var(--el-color-primary)"
|
||||
stroke-width="1.25"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<path
|
||||
d="M152.868 90.1179C152.803 90.0528 152.803 89.9472 152.868 89.8821L154.965 87.7845C155.07 87.6795 155.25 87.7539 155.25 87.9024V92.0976C155.25 92.2461 155.07 92.3205 154.965 92.2155L152.868 90.1179Z"
|
||||
fill="var(--el-color-primary)"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M154.25 89.375L160.25 89.375V90.625L154.25 90.625V89.375Z"
|
||||
fill="var(--el-color-primary)"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M158.583 89.375L164.583 89.375V90.625L158.583 90.625V89.375Z"
|
||||
fill="var(--el-color-primary)"
|
||||
/>
|
||||
<path
|
||||
d="M166.965 89.8821C167.03 89.9472 167.03 90.0528 166.965 90.1179L164.868 92.2155C164.763 92.3205 164.583 92.2461 164.583 92.0976V87.9024C164.583 87.7539 164.763 87.6795 164.868 87.7845L166.965 89.8821Z"
|
||||
fill="var(--el-color-primary)"
|
||||
/>
|
||||
</g>
|
||||
<rect
|
||||
x="80.25"
|
||||
y="56.25"
|
||||
width="119.5"
|
||||
height="67.5"
|
||||
rx="3.75"
|
||||
stroke="var(--el-border-color-dark)"
|
||||
stroke-width="0.5"
|
||||
/>
|
||||
<defs>
|
||||
<clipPath id="clip0_2477_1001">
|
||||
<rect x="80" y="56" width="120" height="68" rx="4" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
</template>
|
||||
1
docs/components.d.ts
vendored
1
docs/components.d.ts
vendored
@@ -103,6 +103,7 @@ declare module 'vue' {
|
||||
OvSkeleton: typeof import('./.vitepress/vitepress/components/overview-icons/ov-skeleton.vue')['default']
|
||||
OvSlider: typeof import('./.vitepress/vitepress/components/overview-icons/ov-slider.vue')['default']
|
||||
OvSpace: typeof import('./.vitepress/vitepress/components/overview-icons/ov-space.vue')['default']
|
||||
OvSplitter: typeof import('./.vitepress/vitepress/components/overview-icons/ov-splitter.vue')['default']
|
||||
OvStatistic: typeof import('./.vitepress/vitepress/components/overview-icons/ov-statistic.vue')['default']
|
||||
OvSteps: typeof import('./.vitepress/vitepress/components/overview-icons/ov-steps.vue')['default']
|
||||
OvSwitch: typeof import('./.vitepress/vitepress/components/overview-icons/ov-switch.vue')['default']
|
||||
|
||||
100
docs/en-US/component/splitter.md
Normal file
100
docs/en-US/component/splitter.md
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: Splitter
|
||||
lang: en-US
|
||||
---
|
||||
|
||||
# Splitter ^(beta)
|
||||
|
||||
Divide the area horizontally or vertically, and freely drag to adjust the size of each area.
|
||||
|
||||
## Basic usage
|
||||
|
||||
The most basic usage, if no default size is passed, it will be automatically divided equally.
|
||||
|
||||
:::demo
|
||||
|
||||
splitter/basic
|
||||
|
||||
:::
|
||||
|
||||
## Vertical
|
||||
|
||||
Use vertical orientation.
|
||||
|
||||
:::demo
|
||||
|
||||
splitter/vertical
|
||||
|
||||
:::
|
||||
|
||||
## Collapsible
|
||||
|
||||
Configuring `collapsible` provides quick shrinking capability. You can use the `min` property to prevent expanding through dragging after collapsing.
|
||||
|
||||
:::demo
|
||||
|
||||
splitter/collapsible
|
||||
|
||||
:::
|
||||
|
||||
## Disable drag
|
||||
|
||||
When either panel disables `resizable`, dragging will be disabled.
|
||||
|
||||
:::demo
|
||||
|
||||
splitter/disableDrag
|
||||
|
||||
:::
|
||||
|
||||
## Panel size
|
||||
|
||||
`v-model:size` can get the panel size.
|
||||
|
||||
:::demo
|
||||
|
||||
splitter/size
|
||||
|
||||
:::
|
||||
|
||||
## Splitter API
|
||||
|
||||
### Splitter Attributes
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| ------ | -------------------------------- | ----------------------------------- | ---------- |
|
||||
| layout | Layout direction of the splitter | ^[enum]`'horizontal' \| 'vertical'` | horizontal |
|
||||
|
||||
### Splitter Events
|
||||
|
||||
| Name | Description | type |
|
||||
| ------------ | ------------------------------------------------------------------------ | ----------------------------------------------------- |
|
||||
| resize-start | Triggered when starting to resize a panel, `index` is the drag bar index | ^[Function]`(index: number, sizes: number[]) => void` |
|
||||
| resize | Triggered while resizing a panel, `index` is the drag bar index | ^[Function]`(index: number, sizes: number[]) => void` |
|
||||
| resize-end | Triggered when panel resizing ends, `index` is the drag bar index | ^[Function]`(index: number, sizes: number[]) => void` |
|
||||
|
||||
## SplitterPanel API
|
||||
|
||||
### SplitterPanel Attributes
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| ------------------- | --------------------------------------------------- | --------------------- | ------- |
|
||||
| size / v-model:size | Size of the panel (in pixels or percentage) | ^[string] / ^[number] | - |
|
||||
| min | Minimum size of the panel (in pixels or percentage) | ^[string] / ^[number] | - |
|
||||
| max | Maximum size of the panel (in pixels or percentage) | ^[string] / ^[number] | - |
|
||||
| resizable | Whether the panel can be resized | ^[boolean] | true |
|
||||
| collapsible | Whether the panel can be collapsed | ^[boolean] | false |
|
||||
|
||||
### SplitterPanel Events
|
||||
|
||||
| Name | Description | type |
|
||||
| ----------- | --------------------------------- | ----------------------------------- |
|
||||
| update:size | Triggered when panel size changes | ^[Function]`(size: number) => void` |
|
||||
|
||||
### SplitterPanel Slots
|
||||
|
||||
| Name | Description |
|
||||
| ----------------- | ----------------------------------------------- |
|
||||
| default | Default content of the panel |
|
||||
| start-collapsible | Custom content for the start collapsible button |
|
||||
| end-collapsible | Custom content for the end collapsible button |
|
||||
23
docs/examples/splitter/basic.vue
Normal file
23
docs/examples/splitter/basic.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div
|
||||
style="height: 250px; box-shadow: var(--el-border-color-light) 0px 0px 10px"
|
||||
>
|
||||
<el-splitter>
|
||||
<el-splitter-panel size="30%">
|
||||
<div class="demo-panel">1</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel :min="200">
|
||||
<div class="demo-panel">2</div>
|
||||
</el-splitter-panel>
|
||||
</el-splitter>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.demo-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
36
docs/examples/splitter/collapsible.vue
Normal file
36
docs/examples/splitter/collapsible.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div
|
||||
style="height: 250px; box-shadow: var(--el-border-color-light) 0px 0px 10px"
|
||||
>
|
||||
<el-splitter>
|
||||
<el-splitter-panel collapsible min="50">
|
||||
<div class="demo-panel">1</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel collapsible>
|
||||
<div class="demo-panel">2</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel>
|
||||
<div class="demo-panel">3</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel collapsible>
|
||||
<el-splitter layout="vertical">
|
||||
<el-splitter-panel collapsible>
|
||||
<div class="demo-panel">4</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel collapsible>
|
||||
<div class="demo-panel">5</div>
|
||||
</el-splitter-panel>
|
||||
</el-splitter>
|
||||
</el-splitter-panel>
|
||||
</el-splitter>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.demo-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
41
docs/examples/splitter/disableDrag.vue
Normal file
41
docs/examples/splitter/disableDrag.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<el-switch
|
||||
v-model="resizable"
|
||||
active-text="enable"
|
||||
inactive-text="disable"
|
||||
inline-prompt
|
||||
class="mb-2"
|
||||
/>
|
||||
<div
|
||||
style="height: 250px; box-shadow: var(--el-border-color-light) 0px 0px 10px"
|
||||
>
|
||||
<el-splitter>
|
||||
<el-splitter-panel>
|
||||
<div class="demo-panel">1</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel :resizable="resizable">
|
||||
<div class="demo-panel">
|
||||
drag {{ resizable ? 'enable' : 'disable' }}
|
||||
</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel>
|
||||
<div class="demo-panel">3</div>
|
||||
</el-splitter-panel>
|
||||
</el-splitter>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const resizable = ref(false)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.demo-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
48
docs/examples/splitter/size.vue
Normal file
48
docs/examples/splitter/size.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div
|
||||
style="height: 250px; box-shadow: var(--el-border-color-light) 0px 0px 10px"
|
||||
>
|
||||
<el-splitter
|
||||
@resize-start="handleResizeStart"
|
||||
@resize-end="handleResizeEnd"
|
||||
@resize="handleResize"
|
||||
>
|
||||
<el-splitter-panel>
|
||||
<div class="demo-panel">1</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel v-model:size="size" :max="200" :min="50">
|
||||
<div class="demo-panel">{{ size }}px</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel>
|
||||
<div class="demo-panel">3</div>
|
||||
</el-splitter-panel>
|
||||
</el-splitter>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const size = ref(100)
|
||||
|
||||
const handleResizeStart = (index: number, sizes: number[]) => {
|
||||
console.log('resizeStart', index, sizes)
|
||||
}
|
||||
|
||||
const handleResize = (index: number, sizes: number[]) => {
|
||||
console.log('resize', index, sizes)
|
||||
}
|
||||
|
||||
const handleResizeEnd = (index: number, sizes: number[]) => {
|
||||
console.log('resizeEnd', index, sizes)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.demo-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
23
docs/examples/splitter/vertical.vue
Normal file
23
docs/examples/splitter/vertical.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div
|
||||
style="height: 250px; box-shadow: var(--el-border-color-light) 0px 0px 10px"
|
||||
>
|
||||
<el-splitter layout="vertical">
|
||||
<el-splitter-panel>
|
||||
<div class="demo-panel">1</div>
|
||||
</el-splitter-panel>
|
||||
<el-splitter-panel>
|
||||
<div class="demo-panel">2</div>
|
||||
</el-splitter-panel>
|
||||
</el-splitter>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.demo-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user