diff --git a/docs/en-US/component/drawer.md b/docs/en-US/component/drawer.md index a20a0e77b8..c9676ee45b 100644 --- a/docs/en-US/component/drawer.md +++ b/docs/en-US/component/drawer.md @@ -53,6 +53,16 @@ drawer/customization-header ::: +## Resizable Drawer ^(2.11.0) + +Try to drag the edge part. + +:::demo Set `resizable` to `true` to resize. + +drawer/resizable-drawer + +::: + ## Nested Drawer You can also have multiple layer of `Drawer` just like `Dialog`. @@ -93,6 +103,7 @@ Drawer provides an API called `destroyOnClose`, which is a flag variable that in | destroy-on-close | Indicates whether children should be destroyed after Drawer closed | ^[boolean] | false | | modal | Should show shadowing layer | ^[boolean] | true | | direction | Drawer's opening direction | ^[enum]`'rtl' \| 'ltr' \| 'ttb' \| 'btt'` | rtl | +| resizable ^(2.11.0) | enable resizable feature for Drawer | ^[boolean] | false | | show-close | Should show close button at the top right of Drawer | ^[boolean] | true | | size | Drawer's size, if Drawer is horizontal mode, it effects the width property, otherwise it effects the height property, when size is `number` type, it describes the size by unit of pixels; when size is `string` type, it should be used with `x%` notation, other wise it will be interpreted to pixel unit | ^[number] / ^[string] | 30% | | title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | ^[string] | — | diff --git a/docs/examples/drawer/resizable-drawer.vue b/docs/examples/drawer/resizable-drawer.vue new file mode 100644 index 0000000000..0be9549b9f --- /dev/null +++ b/docs/examples/drawer/resizable-drawer.vue @@ -0,0 +1,31 @@ + + + diff --git a/packages/components/drawer/__tests__/drawer.test.ts b/packages/components/drawer/__tests__/drawer.test.ts index 0f002073d9..d43af3895d 100644 --- a/packages/components/drawer/__tests__/drawer.test.ts +++ b/packages/components/drawer/__tests__/drawer.test.ts @@ -406,15 +406,15 @@ describe('Drawer', () => { ) test('should effect height when drawer is vertical', async () => { - const drawerEl = renderer('50%', true).find('.el-drawer') - .element as HTMLDivElement - expect(drawerEl.style.width).toEqual('50%') + const wrapper = renderer('50%', true) + const drawerEl = wrapper.findAllComponents({ name: 'ElSplitterPanel' })[0] + expect(drawerEl.vm.size).toContain('50%') }) test('should effect width when drawer is horizontal', async () => { - const drawerEl = renderer('50%', false).find('.el-drawer') - .element as HTMLDivElement - expect(drawerEl.style.height).toEqual('50%') + const wrapper = renderer('50%', false) + const drawerEl = wrapper.findAllComponents({ name: 'ElSplitterPanel' })[0] + expect(drawerEl.vm.size).toContain('50%') }) }) diff --git a/packages/components/drawer/src/drawer.ts b/packages/components/drawer/src/drawer.ts index 72e16e265a..77198bea21 100644 --- a/packages/components/drawer/src/drawer.ts +++ b/packages/components/drawer/src/drawer.ts @@ -10,6 +10,7 @@ export const drawerProps = buildProps({ default: 'rtl', values: ['ltr', 'rtl', 'ttb', 'btt'], }, + resizable: Boolean, size: { type: [String, Number], default: '30%', diff --git a/packages/components/drawer/src/drawer.vue b/packages/components/drawer/src/drawer.vue index fa235420c4..183e81123f 100644 --- a/packages/components/drawer/src/drawer.vue +++ b/packages/components/drawer/src/drawer.vue @@ -26,63 +26,85 @@ @focusout-prevented="onFocusoutPrevented" @release-requested="onCloseRequested" > -
- -
- + +
+
- {{ title }} - - - - - - -
- -
- -
-
+
+ + @@ -95,11 +117,12 @@ import { Close } from '@element-plus/icons-vue' import { ElOverlay } from '@element-plus/components/overlay' import ElFocusTrap from '@element-plus/components/focus-trap' import ElTeleport from '@element-plus/components/teleport' +import ElSplitter, { ElSplitterPanel } from '@element-plus/components/splitter' import { useDialog } from '@element-plus/components/dialog' -import { addUnit } from '@element-plus/utils' import ElIcon from '@element-plus/components/icon' import { useDeprecated, useLocale, useNamespace } from '@element-plus/hooks' import { drawerEmits, drawerProps } from './drawer' +import { addUnit } from '@element-plus/utils' defineOptions({ name: 'ElDrawer', diff --git a/packages/components/drawer/style/css.ts b/packages/components/drawer/style/css.ts index 3f728ca809..1f14b1b636 100644 --- a/packages/components/drawer/style/css.ts +++ b/packages/components/drawer/style/css.ts @@ -1,3 +1,5 @@ import '@element-plus/components/base/style/css' import '@element-plus/theme-chalk/el-drawer.css' import '@element-plus/components/overlay/style/css' +import '@element-plus/components/splitter/style/css' +import '@element-plus/components/splitter-panel/style/css' diff --git a/packages/components/drawer/style/index.ts b/packages/components/drawer/style/index.ts index f9d3239124..25969b0416 100644 --- a/packages/components/drawer/style/index.ts +++ b/packages/components/drawer/style/index.ts @@ -1,3 +1,5 @@ import '@element-plus/components/base/style' import '@element-plus/theme-chalk/src/drawer.scss' import '@element-plus/components/overlay/style' +import '@element-plus/components/splitter/style' +import '@element-plus/components/splitter-panel/style' diff --git a/packages/theme-chalk/src/drawer.scss b/packages/theme-chalk/src/drawer.scss index c7f745120c..3fac781b5c 100644 --- a/packages/theme-chalk/src/drawer.scss +++ b/packages/theme-chalk/src/drawer.scss @@ -9,7 +9,8 @@ $directions: rtl, ltr, ttb, btt; } @include b(drawer) { - position: absolute; + width: 100%; + height: 100%; box-sizing: border-box; background-color: getCssVar('drawer', 'bg-color'); display: flex; @@ -78,35 +79,29 @@ $directions: rtl, ltr, ttb, btt; box-sizing: border-box; } } +} - &.ltr, - &.rtl { - height: 100%; - top: 0; - bottom: 0; - } +.#{$namespace}-drawer-splitter { + $bar: #{$namespace}-splitter-bar; - &.ttb, - &.btt { - width: 100%; - left: 0; - right: 0; - } + > .#{$bar} { + .#{$bar}__disable { + display: none; + } - &.ltr { - left: 0; - } + .#{$bar}__dragger { + &-horizontal::before { + width: 1px; + } - &.rtl { - right: 0; - } + &-vertical::before { + height: 1px; + } - &.ttb { - top: 0; - } - - &.btt { - bottom: 0; + &:not(&-active, &:hover)::before { + background-color: transparent; + } + } } } @@ -114,6 +109,10 @@ $directions: rtl, ltr, ttb, btt; &-enter-active, &-leave-active { transition: all getCssVar('transition-duration'); + + .#{$namespace}-splitter-bar__dragger { + display: none; + } } &-enter-from,