From ca371f7846de0886da07d4f843b1e396577863d9 Mon Sep 17 00:00:00 2001 From: aluarius Date: Wed, 6 Jul 2022 15:49:04 +0600 Subject: [PATCH 01/21] initial --- .../ui/src/components/va-split/VaSplit.vue | 54 +++++++++++++++++++ packages/ui/src/components/va-split/index.ts | 4 ++ 2 files changed, 58 insertions(+) create mode 100644 packages/ui/src/components/va-split/VaSplit.vue create mode 100644 packages/ui/src/components/va-split/index.ts diff --git a/packages/ui/src/components/va-split/VaSplit.vue b/packages/ui/src/components/va-split/VaSplit.vue new file mode 100644 index 0000000000..e72a41016f --- /dev/null +++ b/packages/ui/src/components/va-split/VaSplit.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/packages/ui/src/components/va-split/index.ts b/packages/ui/src/components/va-split/index.ts new file mode 100644 index 0000000000..7a30c6c992 --- /dev/null +++ b/packages/ui/src/components/va-split/index.ts @@ -0,0 +1,4 @@ +import withConfigTransport from '../../services/config-transport/withConfigTransport' +import _VaSplit from './VaSplit.vue' + +export const VaSplit = withConfigTransport(_VaSplit) From cf7769afa9bcc996aa62207ee2f5373b07a6979a Mon Sep 17 00:00:00 2001 From: aluarius Date: Thu, 7 Jul 2022 13:36:22 +0600 Subject: [PATCH 02/21] wip --- .../src/components/va-split/VaSplit.demo.vue | 26 +++++++ .../ui/src/components/va-split/VaSplit.vue | 76 ++++++++++++++----- 2 files changed, 83 insertions(+), 19 deletions(-) create mode 100644 packages/ui/src/components/va-split/VaSplit.demo.vue diff --git a/packages/ui/src/components/va-split/VaSplit.demo.vue b/packages/ui/src/components/va-split/VaSplit.demo.vue new file mode 100644 index 0000000000..f60b538fff --- /dev/null +++ b/packages/ui/src/components/va-split/VaSplit.demo.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/packages/ui/src/components/va-split/VaSplit.vue b/packages/ui/src/components/va-split/VaSplit.vue index e72a41016f..308e9d746a 100644 --- a/packages/ui/src/components/va-split/VaSplit.vue +++ b/packages/ui/src/components/va-split/VaSplit.vue @@ -1,50 +1,88 @@ From 6f75ef3e58295fde205dda6bdce903b10cb2aad0 Mon Sep 17 00:00:00 2001 From: aluarius Date: Sun, 10 Jul 2022 14:52:49 +0600 Subject: [PATCH 03/21] [#1725] split component implementation --- .../components/sidebar/navigationRoutes.ts | 7 + packages/docs/src/locales/en/en.json | 48 ++++- packages/docs/src/locales/ru/ru.json | 48 ++++- .../select/examples/Decorators.vue | 2 +- .../ui-elements/split/api-options.ts | 9 + .../split/examples/CustomGrabber.vue | 27 +++ .../ui-elements/split/examples/Default.vue | 35 ++++ .../ui-elements/split/examples/Disabled.vue | 22 +++ .../split/examples/Maximization.vue | 22 +++ .../ui-elements/split/examples/Nested.vue | 36 ++++ .../ui-elements/split/examples/Vertical.vue | 22 +++ .../ui-elements/split/page-config.ts | 61 ++++++ packages/docs/src/pages/ui-elements/split.vue | 20 ++ .../src/components/va-backtop/VaBacktop.vue | 2 +- .../src/components/va-split/VaSplit.demo.vue | 129 ++++++++++++- .../ui/src/components/va-split/VaSplit.vue | 175 ++++++++++++++---- .../src/components/va-split/_variables.scss | 12 ++ .../src/styles/grid/_grid-global-styles.scss | 4 + 18 files changed, 633 insertions(+), 48 deletions(-) create mode 100644 packages/docs/src/page-configs/ui-elements/split/api-options.ts create mode 100644 packages/docs/src/page-configs/ui-elements/split/examples/CustomGrabber.vue create mode 100644 packages/docs/src/page-configs/ui-elements/split/examples/Default.vue create mode 100644 packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue create mode 100644 packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue create mode 100644 packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue create mode 100644 packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue create mode 100644 packages/docs/src/page-configs/ui-elements/split/page-config.ts create mode 100644 packages/docs/src/pages/ui-elements/split.vue create mode 100644 packages/ui/src/components/va-split/_variables.scss diff --git a/packages/docs/src/components/sidebar/navigationRoutes.ts b/packages/docs/src/components/sidebar/navigationRoutes.ts index dfb8b1e284..5a8b17b7dd 100644 --- a/packages/docs/src/components/sidebar/navigationRoutes.ts +++ b/packages/docs/src/components/sidebar/navigationRoutes.ts @@ -242,6 +242,13 @@ export const navigationRoutes: NavigationRoute[] = [ name: 'list', displayName: 'menu.list', }, + { + name: 'split', + displayName: 'menu.split', + meta: { + badge: 'new', + }, + }, { name: 'collapse', displayName: 'menu.collapse', diff --git a/packages/docs/src/locales/en/en.json b/packages/docs/src/locales/en/en.json index 288fe24a51..8451742796 100644 --- a/packages/docs/src/locales/en/en.json +++ b/packages/docs/src/locales/en/en.json @@ -1272,6 +1272,21 @@ "events": {}, "methods": {}, "slots": {} + }, + "VaSplit": { + "props": { + "vertical": "Changes `va-split` orientation to vertical.", + "limits": "Array of maximal sizes (%) for start/end panels.", + "maximization": "End panel size maximization via separator double click.", + "maximizeStart": "Maximize size of the start panel instead of end one." + }, + "events": {}, + "methods": {}, + "slots": { + "dragger": "Changes default separator-dragger (`va-divider` component) to custom.", + "start": "Start panel content.", + "end": "End panel content." + } } }, "menu": { @@ -1381,7 +1396,8 @@ "counter": "Counter", "nuxt": "Nuxt", "ssrGuide": "SSR", - "spacer": "Spacer" + "spacer": "Spacer", + "split": "Split" }, "all": { "examples": "Examples", @@ -4125,5 +4141,35 @@ "text": "`va-spacer` adding a div with the `.va-spacer` class." } } + }, + "split": { + "title": "Split", + "summaryText": "`va-split` component splits container into 2 horizontal/vertical panels. You can change panels sizes via grabbing the separator-grabber between them.", + "examples": { + "default": { + "title": "Basic usage", + "text": "" + }, + "vertical": { + "title": "Vertical", + "text": "Prop `vertical` changes components orientation to vertical." + }, + "customGrabber": { + "title": "Custom grabber", + "text": "You can pass via `grabber` slot any content which will overwrite default grabber (`va-divider`)." + }, + "nested": { + "title": "Nested", + "text": "Passing another `va-split` component via `start`/`end` slot you can gain different panels combinations." + }, + "maximization": { + "title": "Maximization", + "text": "Prop `maximization` allows to maximize end panel size via double click on dragger (additional prop `maximizeStart` changes this logic - start panel maximizing instead)." + }, + "disabled": { + "title": "Disabled", + "text": "`disabled` prop restricts to change panels size (including option via `maximization` prop)." + } + } } } diff --git a/packages/docs/src/locales/ru/ru.json b/packages/docs/src/locales/ru/ru.json index e1862ff9c2..2dd53ac12f 100644 --- a/packages/docs/src/locales/ru/ru.json +++ b/packages/docs/src/locales/ru/ru.json @@ -1202,6 +1202,21 @@ "events": {}, "methods": {}, "slots": {} + }, + "VaSplit": { + "props": { + "vertical": "Меняет ориентацию сплиттера на вертикальную.", + "limits": "Массив максимальных размеров (в %) начальной и конечной панели.", + "maximization": "Активирует возможность максимизации размера конечной панели при двойном клике по разделителю.", + "maximizeStart": "Меняет логику максимизации с конечной на начальную панель." + }, + "events": {}, + "methods": {}, + "slots": { + "dragger": "Заменяет стандартный перетаскиваемый разделитель, использующий компонент `va-divider`, на пользовательский.", + "start": "Содержимое первой панели.", + "end": "Содержимое второй панели." + } } }, "menu": { @@ -1311,7 +1326,8 @@ "counter": "Counter", "nuxt": "Nuxt", "ssrGuide": "Ssr Guide", - "spacer": "Spacer" + "spacer": "Spacer", + "split": "Split" }, "all": { "examples": "Примеры", @@ -3966,5 +3982,35 @@ "text": "`va-spacer` добавляет div с классом `.va-spacer`." } } + }, + "split": { + "title": "Split", + "summaryText": "Компонент `va-split` разделяет контейнер на 2 горизонтальные или вертикальные панели с возможностью изменения их размеров путем перетаскивания разделителя между ними.", + "examples": { + "default": { + "title": "Базовое использование", + "text": "" + }, + "vertical": { + "title": "Vertical", + "text": "Свойство `vertical` позволяет изменить ориентацию компонента на вертикальную." + }, + "customGrabber": { + "title": "Кастомный разделитель", + "text": "Передав содержимое в слот `grabber`, оно заменит стандартный разделитель-граббер." + }, + "nested": { + "title": "Вложенность", + "text": "Передавая в слоты `start`/`end` еще один `va-split`, можно создавать любые комбинации панелей." + }, + "maximization": { + "title": "Максимизация по двойному клику", + "text": "Свойство `maximization` позволяет максимизировать размер конечной панели через двойной клик по разделителю (дополнительной свойство `maximizeStart` меняет логику - максимизируется начальная панель)." + }, + "disabled": { + "title": "Disabled", + "text": "Свойство `disabled` отключает возможность изменения размеров панелей (в т.ч. через свойство `maximization`)." + } + } } } diff --git a/packages/docs/src/page-configs/ui-elements/select/examples/Decorators.vue b/packages/docs/src/page-configs/ui-elements/select/examples/Decorators.vue index 1c48dc9f68..67355f1eb3 100644 --- a/packages/docs/src/page-configs/ui-elements/select/examples/Decorators.vue +++ b/packages/docs/src/page-configs/ui-elements/select/examples/Decorators.vue @@ -8,7 +8,7 @@ /> + + + + + + + + diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue new file mode 100644 index 0000000000..6c1bf8ac46 --- /dev/null +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue new file mode 100644 index 0000000000..ca7618eec8 --- /dev/null +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue new file mode 100644 index 0000000000..e81d571087 --- /dev/null +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue new file mode 100644 index 0000000000..67b40dd3d6 --- /dev/null +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue @@ -0,0 +1,36 @@ + + + diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue new file mode 100644 index 0000000000..3398168d2d --- /dev/null +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/docs/src/page-configs/ui-elements/split/page-config.ts b/packages/docs/src/page-configs/ui-elements/split/page-config.ts new file mode 100644 index 0000000000..65ea5ed10d --- /dev/null +++ b/packages/docs/src/page-configs/ui-elements/split/page-config.ts @@ -0,0 +1,61 @@ +import { ApiDocsBlock } from '@/types/configTypes' +import { PageGenerationHelper } from '@/helpers/DocsHelper' +import VaSplit from 'vuestic-ui/src/components/va-split/VaSplit.vue' +import apiOptions from './api-options' + +// @ts-ignore +// eslint-disable-next-line import/no-webpack-loader-syntax +const cssVariables = import('!raw-loader!vuestic-ui/src/components/va-split/_variables.scss') + +const block = new PageGenerationHelper(__dirname) + +const config: ApiDocsBlock[] = [ + block.title('split.title'), + block.paragraph('split.summaryText'), + + block.subtitle('all.examples'), + + ...block.exampleBlock( + 'split.examples.default.title', + '', + 'Default', + ), + + ...block.exampleBlock( + 'split.examples.vertical.title', + 'split.examples.vertical.text', + 'Vertical', + ), + + ...block.exampleBlock( + 'split.examples.customGrabber.title', + 'split.examples.customGrabber.text', + 'CustomGrabber', + ), + + ...block.exampleBlock( + 'split.examples.nested.title', + 'split.examples.nested.text', + 'Nested', + ), + + ...block.exampleBlock( + 'split.examples.maximization.title', + 'split.examples.maximization.text', + 'Maximization', + ), + + ...block.exampleBlock( + 'split.examples.disabled.title', + 'split.examples.disabled.text', + 'Disabled', + ), + + block.subtitle('all.api'), + block.api(VaSplit, apiOptions), + + block.subtitle('all.cssVariables'), + block.file(cssVariables), +] + +export default config diff --git a/packages/docs/src/pages/ui-elements/split.vue b/packages/docs/src/pages/ui-elements/split.vue new file mode 100644 index 0000000000..c64392732b --- /dev/null +++ b/packages/docs/src/pages/ui-elements/split.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/ui/src/components/va-backtop/VaBacktop.vue b/packages/ui/src/components/va-backtop/VaBacktop.vue index b997edd104..57326efb90 100644 --- a/packages/ui/src/components/va-backtop/VaBacktop.vue +++ b/packages/ui/src/components/va-backtop/VaBacktop.vue @@ -20,7 +20,7 @@ - + diff --git a/packages/ui/src/components/va-split/VaSplit.vue b/packages/ui/src/components/va-split/VaSplit.vue index 308e9d746a..4073023d11 100644 --- a/packages/ui/src/components/va-split/VaSplit.vue +++ b/packages/ui/src/components/va-split/VaSplit.vue @@ -1,92 +1,189 @@ diff --git a/packages/ui/src/components/va-split/_variables.scss b/packages/ui/src/components/va-split/_variables.scss new file mode 100644 index 0000000000..0e32af6502 --- /dev/null +++ b/packages/ui/src/components/va-split/_variables.scss @@ -0,0 +1,12 @@ +:root { + --va-split-panel-overflow: scroll; + + --va-split-dragger-display: flex; + --va-split-dragger-size: 1rem; + --va-split-dragger-justify-content: center; + --va-split-dragger-align-items: center; + + --va-split-dragging-cursor: grabbing; + --va-split-horizontal-dragger-cursor: col-resize; + --va-split-vertical-dragger-cursor: row-resize; +} \ No newline at end of file diff --git a/packages/ui/src/styles/grid/_grid-global-styles.scss b/packages/ui/src/styles/grid/_grid-global-styles.scss index d2539fdd92..b666138f30 100644 --- a/packages/ui/src/styles/grid/_grid-global-styles.scss +++ b/packages/ui/src/styles/grid/_grid-global-styles.scss @@ -260,6 +260,10 @@ height: 100%; } +.fill-width { + width: 100%; +} + .no-wrap { @include va-no-wrap(); } From 2ca210264e6c45f4dd3743192b87a299e367b9c3 Mon Sep 17 00:00:00 2001 From: aluarius Date: Sun, 10 Jul 2022 14:53:55 +0600 Subject: [PATCH 04/21] [#1725] split component implementation --- packages/ui/src/components/va-split/_variables.scss | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/ui/src/components/va-split/_variables.scss b/packages/ui/src/components/va-split/_variables.scss index 0e32af6502..ea8b39eabe 100644 --- a/packages/ui/src/components/va-split/_variables.scss +++ b/packages/ui/src/components/va-split/_variables.scss @@ -1,12 +1,10 @@ :root { --va-split-panel-overflow: scroll; - --va-split-dragger-display: flex; --va-split-dragger-size: 1rem; --va-split-dragger-justify-content: center; --va-split-dragger-align-items: center; - --va-split-dragging-cursor: grabbing; --va-split-horizontal-dragger-cursor: col-resize; --va-split-vertical-dragger-cursor: row-resize; -} \ No newline at end of file +} From 460023f3691fa70ee3438858cbe1e0482d8f0d09 Mon Sep 17 00:00:00 2001 From: aluarius Date: Mon, 11 Jul 2022 21:38:26 +0600 Subject: [PATCH 05/21] fix:review suggestions, refactoring --- .../split/examples/CustomGrabber.vue | 19 +++++- .../ui-elements/split/examples/Default.vue | 44 +++++++++++++- .../ui-elements/split/examples/Disabled.vue | 4 +- .../split/examples/Maximization.vue | 4 +- .../ui-elements/split/examples/Nested.vue | 8 +-- .../ui-elements/split/examples/Vertical.vue | 4 +- .../src/components/va-split/VaSplit.demo.vue | 51 +++++++++------- .../ui/src/components/va-split/VaSplit.vue | 55 +++++++---------- .../components/va-split/useSplitDragger.ts | 60 +++++++++++++++++++ .../ui/src/styles/global/_utility-global.scss | 4 ++ .../src/styles/grid/_grid-global-styles.scss | 4 -- 11 files changed, 184 insertions(+), 73 deletions(-) create mode 100644 packages/ui/src/components/va-split/useSplitDragger.ts diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/CustomGrabber.vue b/packages/docs/src/page-configs/ui-elements/split/examples/CustomGrabber.vue index 0951fbaaa7..61eefc49bb 100644 --- a/packages/docs/src/page-configs/ui-elements/split/examples/CustomGrabber.vue +++ b/packages/docs/src/page-configs/ui-elements/split/examples/CustomGrabber.vue @@ -1,15 +1,15 @@ @@ -25,3 +25,16 @@ export default { }), } + + diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue index 6c1bf8ac46..a0d00e7017 100644 --- a/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue @@ -1,10 +1,14 @@ @@ -24,6 +28,7 @@ export default { diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue index ca7618eec8..13832d1560 100644 --- a/packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Disabled.vue @@ -1,10 +1,10 @@ diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue index e81d571087..afaa139c9c 100644 --- a/packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Maximization.vue @@ -1,10 +1,10 @@ diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue index 67b40dd3d6..5a67663e0d 100644 --- a/packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Nested.vue @@ -3,20 +3,20 @@ diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue index 3398168d2d..a555ee3776 100644 --- a/packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Vertical.vue @@ -1,10 +1,10 @@ diff --git a/packages/ui/src/components/va-split/VaSplit.demo.vue b/packages/ui/src/components/va-split/VaSplit.demo.vue index ffa64fd8f8..787803c09b 100644 --- a/packages/ui/src/components/va-split/VaSplit.demo.vue +++ b/packages/ui/src/components/va-split/VaSplit.demo.vue @@ -3,10 +3,10 @@ @@ -14,10 +14,10 @@ @@ -25,15 +25,15 @@ @@ -41,10 +41,10 @@ @@ -52,10 +52,10 @@ @@ -63,10 +63,10 @@ @@ -74,10 +74,10 @@ @@ -87,20 +87,20 @@ @@ -110,10 +110,10 @@ @@ -141,5 +141,14 @@ export default { padding: 0.5rem; } } + + & .custom-grabber { + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + background-color: greenyellow; + } } diff --git a/packages/ui/src/components/va-split/VaSplit.vue b/packages/ui/src/components/va-split/VaSplit.vue index 4073023d11..8011d08635 100644 --- a/packages/ui/src/components/va-split/VaSplit.vue +++ b/packages/ui/src/components/va-split/VaSplit.vue @@ -5,8 +5,7 @@ class="va-split" :class="classComputed" @mousemove="processDragging" - @mouseup="stopDragging" - @mouseleave="stopDragging"> + @mouseup="stopDragging">
@@ -16,6 +15,7 @@ class="va-split__dragger" :style="draggerStyleComputed" @mousedown="startDragging" + @touchstart="startDragging" @dblclick="maximizePanel"> import { defineComponent, PropType, ref, shallowRef, computed, watch } from 'vue' import { useBem, useComponentPresetProp, useStateful, useStatefulEmits, useStatefulProps } from '../../composables' +import { useSplitDragger, useSplitDraggerProps } from './useSplitDragger' import { __DEV__ } from '../../utils/global-utils' import { VaDivider } from '../va-divider' @@ -45,14 +46,13 @@ export default defineComponent({ props: { ...useComponentPresetProp, + ...useSplitDraggerProps, ...useStatefulProps, modelValue: { type: Number, default: 50, validator: (v: number) => v <= 100, }, - vertical: { type: Boolean, default: false }, - disabled: { type: Boolean, default: false }, maximization: { type: Boolean, default: false }, maximizeStart: { type: Boolean, default: false }, limits: { type: Array as any as PropType<[number, number]>, default: () => [30, 70] }, @@ -65,7 +65,7 @@ export default defineComponent({ const splitPanelsContainer = shallowRef() const containerSizeComputed = computed(() => { - if (!splitPanelsContainer.value) { return undefined } + if (!splitPanelsContainer.value) { return } return props.vertical ? splitPanelsContainer.value.offsetHeight : splitPanelsContainer.value.offsetWidth }) @@ -76,25 +76,13 @@ export default defineComponent({ return splitterPosition.value }) - const isDragging = ref(false) - const dragStartPosition = ref(0) - const dragStartSplitterPosition = ref(0) - - const startDragging = (e: MouseEvent) => { - if (props.disabled || !containerSizeComputed.value) { return } - - isDragging.value = true - dragStartPosition.value = props.vertical ? e.pageY : e.pageX - dragStartSplitterPosition.value = splitterPositionComputed.value - } - - const processDragging = (e: MouseEvent) => { - if (!isDragging.value) { return } - - const currentPosition = props.vertical ? e.pageY : e.pageX - const distance = currentPosition - dragStartPosition.value - splitterPosition.value = dragStartSplitterPosition.value + Math.floor((distance / containerSizeComputed.value!) * 100) - } + const { + isDragging, + startDragging, + processDragging, + stopDragging, + currentSplitterPosition, + } = useSplitDragger(containerSizeComputed, splitterPositionComputed, props) const maximizePanel = () => { if (!props.maximization || props.disabled) { return } @@ -102,11 +90,6 @@ export default defineComponent({ splitterPosition.value = props.maximizeStart ? props.limits[1] : props.limits[0] } - const stopDragging = () => { - valueComputed.value = splitterPositionComputed.value - isDragging.value = false - } - watch(valueComputed, (v) => { if (__DEV__ && (v < props.limits[0] || v > props.limits[1])) { console.warn('Incorrect `modelValue`. Check current `limits` value.') @@ -115,6 +98,15 @@ export default defineComponent({ splitterPosition.value = v }) + watch(currentSplitterPosition, (v) => { + splitterPosition.value = v + }) + + watch(isDragging, (v) => { + if (!v) { valueComputed.value = splitterPositionComputed.value } + document.documentElement.style.cursor = v ? 'var(--va-split-dragging-cursor)' : '' + }) + const sizePropertyComputed = computed(() => props.vertical ? 'height' : 'width') const getPanelStyle = (position: 'start' | 'end') => ({ [sizePropertyComputed.value]: `${position === 'start' ? splitterPositionComputed.value : 100 - splitterPositionComputed.value}%`, @@ -122,9 +114,8 @@ export default defineComponent({ const draggerStyleComputed = computed(() => { if (props.disabled) { return {} } - let cursor = props.vertical ? 'var(--va-split-vertical-dragger-cursor)' : 'var(--va-split-horizontal-dragger-cursor)' - if (isDragging.value) { cursor = 'var(--va-split-dragging-cursor)' } - return { cursor } + if (isDragging.value) { return { cursor: 'var(--va-split-dragging-cursor)' } } + return { cursor: props.vertical ? 'var(--va-split-vertical-dragger-cursor)' : 'var(--va-split-horizontal-dragger-cursor)' } }) const classComputed = useBem('va-split', () => ({ diff --git a/packages/ui/src/components/va-split/useSplitDragger.ts b/packages/ui/src/components/va-split/useSplitDragger.ts new file mode 100644 index 0000000000..c57149747f --- /dev/null +++ b/packages/ui/src/components/va-split/useSplitDragger.ts @@ -0,0 +1,60 @@ +import { ExtractPropTypes, onBeforeUnmount, onMounted, ref, Ref } from 'vue' + +export const useSplitDraggerProps = { + vertical: { type: Boolean, default: false }, + disabled: { type: Boolean, default: false }, +} + +export const useSplitDragger = ( + containerSizeComputed: Ref, + splitterPositionComputed: Ref, + props: ExtractPropTypes, +) => { + const isDragging = ref(false) + const dragStartPosition = ref(0) + const dragStartSplitterPosition = ref(0) + const currentSplitterPosition = ref(0) + + const getEventPosition = (e: MouseEvent | TouchEvent, eventName: 'mousemove' | 'mousedown'): number => { + const event = e.type === eventName ? e as MouseEvent : (e as TouchEvent).changedTouches[0] + return props.vertical ? event.pageY : event.pageX + } + + const startDragging = (e: MouseEvent | TouchEvent) => { + if (props.disabled || !containerSizeComputed.value) { return } + + isDragging.value = true + dragStartPosition.value = getEventPosition(e, 'mousedown') + dragStartSplitterPosition.value = splitterPositionComputed.value + } + + const processDragging = (e: MouseEvent | TouchEvent) => { + if (!isDragging.value) { return } + + const currentPosition = getEventPosition(e, 'mousemove') + const distance = currentPosition - dragStartPosition.value + currentSplitterPosition.value = dragStartSplitterPosition.value + Math.floor((distance / containerSizeComputed.value!) * 100) + } + + const stopDragging = () => { + isDragging.value = false + } + + onMounted(() => { + document.addEventListener('mousemove', processDragging) + document.addEventListener('touchmove', processDragging) + document.addEventListener('mouseup', stopDragging) + document.addEventListener('mouseleave', stopDragging) + document.addEventListener('touchcancel', stopDragging) + }) + + onBeforeUnmount(() => { + document.removeEventListener('mousemove', processDragging) + document.removeEventListener('touchmove', processDragging) + document.removeEventListener('mouseup', stopDragging) + document.removeEventListener('mouseleave', stopDragging) + document.removeEventListener('touchcancel', stopDragging) + }) + + return { isDragging, startDragging, processDragging, stopDragging, currentSplitterPosition } +} diff --git a/packages/ui/src/styles/global/_utility-global.scss b/packages/ui/src/styles/global/_utility-global.scss index 97aa3f3d24..02d8e1440b 100644 --- a/packages/ui/src/styles/global/_utility-global.scss +++ b/packages/ui/src/styles/global/_utility-global.scss @@ -23,3 +23,7 @@ .visually-hidden { @include visually-hidden; } + +.fill-width { + width: 100%; +} diff --git a/packages/ui/src/styles/grid/_grid-global-styles.scss b/packages/ui/src/styles/grid/_grid-global-styles.scss index b666138f30..d2539fdd92 100644 --- a/packages/ui/src/styles/grid/_grid-global-styles.scss +++ b/packages/ui/src/styles/grid/_grid-global-styles.scss @@ -260,10 +260,6 @@ height: 100%; } -.fill-width { - width: 100%; -} - .no-wrap { @include va-no-wrap(); } From ab71406125ab22aba15736981b329f12a8f28581 Mon Sep 17 00:00:00 2001 From: aluarius Date: Tue, 12 Jul 2022 23:20:38 +0600 Subject: [PATCH 06/21] fix:deleted redundant events fix:minor fix fix:redundant limits prop changed to number --- .../ui/src/components/va-split/VaSplit.vue | 23 +++++++++++-------- .../components/va-split/useSplitDragger.ts | 2 -- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/ui/src/components/va-split/VaSplit.vue b/packages/ui/src/components/va-split/VaSplit.vue index 8011d08635..34cf0f8797 100644 --- a/packages/ui/src/components/va-split/VaSplit.vue +++ b/packages/ui/src/components/va-split/VaSplit.vue @@ -3,9 +3,7 @@ ref="splitPanelsContainer" aria-label="split panels" class="va-split" - :class="classComputed" - @mousemove="processDragging" - @mouseup="stopDragging"> + :class="classComputed">
@@ -32,7 +30,7 @@ diff --git a/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue b/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue index a0d00e7017..3871f89a0e 100644 --- a/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue +++ b/packages/docs/src/page-configs/ui-elements/split/examples/Default.vue @@ -1,5 +1,5 @@