@zeedhi/vuetify 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/zd-vuetify.css +30 -19
- package/dist/zd-vuetify.min.css +2 -2
- package/dist/zd-vuetify.min.js +15 -17
- package/dist/zd-vuetify.mjs +678 -368
- package/package.json +3 -3
- package/src/components/zd-checkbox/ZdCheckbox.vue +4 -0
- package/src/components/zd-component/ZdComponent.ts +15 -13
- package/src/components/zd-date-input/ZdDateInput.ts +1 -0
- package/src/components/zd-grid-editable/ZdGridEditable.ts +16 -13
- package/src/components/zd-select/ZdSelect.ts +18 -1
- package/src/components/zd-select/ZdSelect.vue +3 -2
- package/src/components/zd-select-multiple/ZdSelectMultiple.ts +21 -3
- package/src/components/zd-select-multiple/ZdSelectMultiple.vue +10 -1
- package/src/components/zd-tabs/ZdTab.ts +40 -6
- package/src/components/zd-tabs/ZdTab.vue +16 -3
- package/src/components/zd-tabs/ZdTabItem.ts +2 -2
- package/src/components/zd-tabs/ZdTabItem.vue +3 -1
- package/src/components/zd-tabs/ZdTabs.ts +96 -2
- package/src/components/zd-tabs/ZdTabs.vue +46 -17
- package/src/components/zd-text-input/ZdTextInput.ts +6 -0
- package/src/components/zd-text-input/ZdTextInput.vue +1 -1
- package/src/components/zd-textarea/ZdTextarea.vue +1 -0
- package/src/components/zd-tooltip/ZdTooltip.vue +2 -1
- package/src/composables/gridColumns.ts +11 -6
- package/types/components/zd-alert/ZdAlert.d.ts +299 -299
- package/types/components/zd-badge/ZdBadge.d.ts +159 -159
- package/types/components/zd-breadcrumbs/ZdBreadcrumbs.d.ts +168 -168
- package/types/components/zd-button/ZdButton.d.ts +159 -159
- package/types/components/zd-button-group/ZdButtonGroup.d.ts +168 -168
- package/types/components/zd-card/ZdCard.d.ts +159 -159
- package/types/components/zd-carousel/ZdCarousel.d.ts +476 -476
- package/types/components/zd-checkbox-multiple/ZdCheckboxMultiple.d.ts +599 -599
- package/types/components/zd-chip/ZdChip.d.ts +159 -159
- package/types/components/zd-code-viewer/ZdCodeViewer.d.ts +168 -168
- package/types/components/zd-col/ZdCol.d.ts +168 -168
- package/types/components/zd-collapse-card/ZdCollapseCard.d.ts +374 -374
- package/types/components/zd-container/ZdContainer.d.ts +168 -168
- package/types/components/zd-currency/ZdCurrency.d.ts +595 -595
- package/types/components/zd-date-range/ZdDateRange.d.ts +600 -597
- package/types/components/zd-divider/ZdDivider.d.ts +168 -168
- package/types/components/zd-dropdown/ZdDropdown.d.ts +252 -252
- package/types/components/zd-footer/ZdFooter.d.ts +420 -420
- package/types/components/zd-frame-page/ZdFramePage.d.ts +160 -160
- package/types/components/zd-grid/ZdGrid.d.ts +2976 -2976
- package/types/components/zd-grid/composables/grid-instance.d.ts +1351 -1351
- package/types/components/zd-grid/footer/ZdGridFooter.d.ts +1351 -1351
- package/types/components/zd-grid/toolbar/ZdGridToolbar.d.ts +1351 -1351
- package/types/components/zd-grid-editable/ZdGridEditable.d.ts +2977 -2979
- package/types/components/zd-grid-editable/cell/ZdGridEditableCell.d.ts +271 -271
- package/types/components/zd-header/ZdHeader.d.ts +412 -412
- package/types/components/zd-image/ZdImage.d.ts +168 -168
- package/types/components/zd-increment/ZdIncrement.d.ts +595 -595
- package/types/components/zd-iterable/ZdIterableNoData.d.ts +1351 -1351
- package/types/components/zd-iterable/zd-iterable-columns-button/ZdIterableColumnsButton.d.ts +472 -472
- package/types/components/zd-iterable/zd-iterable-page-info/ZdIterablePageInfo.d.ts +481 -481
- package/types/components/zd-iterable/zd-iterable-page-size/ZdIterablePageSize.d.ts +1080 -1080
- package/types/components/zd-iterable/zd-iterable-pagination/ZdIterablePagination.d.ts +481 -481
- package/types/components/zd-iterable-component-render/ZdIterableComponentRender.d.ts +816 -816
- package/types/components/zd-layout/ZdLayout.d.ts +168 -168
- package/types/components/zd-list/ZdList.d.ts +447 -447
- package/types/components/zd-list/ZdListGroup.d.ts +560 -560
- package/types/components/zd-list/ZdListItem.d.ts +280 -280
- package/types/components/zd-login/ZdLogin.d.ts +336 -336
- package/types/components/zd-login/ZdLoginButton.d.ts +526 -526
- package/types/components/zd-main/ZdMain.d.ts +168 -168
- package/types/components/zd-master-detail/ZdMasterDetail.d.ts +167 -167
- package/types/components/zd-menu/ZdMenu.d.ts +3060 -1068
- package/types/components/zd-menu/ZdMenuButton.d.ts +159 -159
- package/types/components/zd-menu/ZdMenuGroup.d.ts +5205 -1000
- package/types/components/zd-menu/ZdMenuLink.d.ts +8943 -1529
- package/types/components/zd-menu/ZdMenuSeparator.d.ts +168 -168
- package/types/components/zd-modal/ZdModalCloseButton.d.ts +159 -159
- package/types/components/zd-month/ZdMonth.d.ts +598 -597
- package/types/components/zd-number-input/ZdNumberInput.d.ts +596 -596
- package/types/components/zd-password/ZdPassword.d.ts +595 -595
- package/types/components/zd-progress/ZdProgress.d.ts +252 -252
- package/types/components/zd-row/ZdRow.d.ts +168 -168
- package/types/components/zd-switch/ZdSwitch.d.ts +595 -595
- package/types/components/zd-table/ZdTable.d.ts +313 -313
- package/types/components/zd-tabs/ZdTab.d.ts +144 -150
- package/types/components/zd-tabs/ZdTabItem.d.ts +6 -6
- package/types/components/zd-tabs/ZdTabs.d.ts +330 -311
- package/types/components/zd-tag/ZdTag.d.ts +168 -168
- package/types/components/zd-text/ZdText.d.ts +168 -168
- package/types/components/zd-time/ZdTime.d.ts +595 -595
- package/types/components/zd-tooltip/ZdTooltip.d.ts +168 -168
- package/types/components/zd-tree/ZdTree.d.ts +591 -591
- package/types/components/zd-tree-grid/ZdTreeGrid.d.ts +1485 -1485
- package/types/composables/gridColumns.d.ts +140 -140
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeedhi/vuetify",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Zeedhi Components based on Vuetify",
|
|
5
5
|
"author": "Zeedhi <zeedhi@teknisa.com>",
|
|
6
6
|
"license": "ISC",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@vitest/coverage-v8": "^2.1.3",
|
|
43
43
|
"@zeedhi/common": "^3.0.0",
|
|
44
44
|
"@zeedhi/core": "^3.0.0",
|
|
45
|
-
"@zeedhi/vue": "^3.
|
|
45
|
+
"@zeedhi/vue": "^3.3.0",
|
|
46
46
|
"vue": "^3.0.0",
|
|
47
47
|
"vue-router": "^4.2.2",
|
|
48
48
|
"vuetify": "^3.11.0"
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"env": {
|
|
59
59
|
"NODE_ENV": "production"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "3398ef763d8812e5b8feb5b8f06db1b377271fde"
|
|
62
62
|
}
|
|
@@ -235,7 +235,7 @@ export function useCreateInstance<T extends Component, G extends RootRef = RootR
|
|
|
235
235
|
explicitlyPassedProps[key] = props[key];
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
|
-
explicitlyPassedProps.
|
|
238
|
+
delete explicitlyPassedProps.instanceObject;
|
|
239
239
|
|
|
240
240
|
const events = getInstanceEvents([props.events, props.instanceObject.events]);
|
|
241
241
|
|
|
@@ -267,18 +267,20 @@ export function useCreateInstance<T extends Component, G extends RootRef = RootR
|
|
|
267
267
|
const instance = reactive(instanceObj);
|
|
268
268
|
|
|
269
269
|
// criar reatividades nas propriedades. (PropWatch)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
(
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
270
|
+
if (!createdFromObject) {
|
|
271
|
+
Object.keys(props).forEach((key: string) => {
|
|
272
|
+
if (!(key in instance)) return;
|
|
273
|
+
if (typeof props[key] === 'function') return;
|
|
274
|
+
if (propsDefs[key]?.watch === false) return;
|
|
275
|
+
|
|
276
|
+
watch(
|
|
277
|
+
() => props[key],
|
|
278
|
+
value => {
|
|
279
|
+
(instance as any)[key] = value;
|
|
280
|
+
},
|
|
281
|
+
);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
282
284
|
|
|
283
285
|
addChild({ instance, props });
|
|
284
286
|
|
|
@@ -16,6 +16,7 @@ import { RowNotFoundError } from '../../errors';
|
|
|
16
16
|
import { buildProps } from '../../utils';
|
|
17
17
|
import { getRootElement, useCreateInstance } from '../zd-component/ZdComponent';
|
|
18
18
|
import { ZdGridProps, useGridInstance } from '../zd-grid/ZdGrid';
|
|
19
|
+
import debounce from 'lodash.debounce';
|
|
19
20
|
|
|
20
21
|
export const ZdGridEditableProps = buildProps({
|
|
21
22
|
...ZdGridProps,
|
|
@@ -89,22 +90,24 @@ export function useGridEditableInstance({
|
|
|
89
90
|
const key = instance.getRowKey(row);
|
|
90
91
|
editingCell.value = { key, column: column.name };
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
checkToggleComponent(row, column);
|
|
94
|
+
};
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
component?.setFocus();
|
|
96
|
+
const checkToggleComponent = debounce((row: IDictionary, column: GridColumnEditable) => {
|
|
97
|
+
const key = instance.getRowKey(row);
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
try {
|
|
100
|
+
const component = instance.getComponent<Input>(String(key), column.name);
|
|
101
|
+
component?.setFocus();
|
|
102
|
+
|
|
103
|
+
if (component instanceof Toggleable) {
|
|
104
|
+
component.toggleValue();
|
|
105
|
+
component.change();
|
|
105
106
|
}
|
|
106
|
-
})
|
|
107
|
-
|
|
107
|
+
} catch (e) {
|
|
108
|
+
if (!(e instanceof InstanceNotFoundError)) throw e;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
108
111
|
|
|
109
112
|
const viewEnterEdit = (key: string, columnName: string) => {
|
|
110
113
|
editingCell.value = { key, column: columnName };
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { Select } from '@zeedhi/common';
|
|
2
2
|
import { FormatterParserProvider, IDictionary } from '@zeedhi/core';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ComponentPublicInstance,
|
|
5
|
+
Ref,
|
|
6
|
+
SetupContext,
|
|
7
|
+
UnwrapNestedRefs,
|
|
8
|
+
computed,
|
|
9
|
+
defineComponent,
|
|
10
|
+
useSlots,
|
|
11
|
+
} from 'vue';
|
|
4
12
|
import { useDensity } from '../../composables';
|
|
5
13
|
import { buildProps } from '../../utils';
|
|
6
14
|
import { getRootElement } from '../zd-component/ZdComponent';
|
|
@@ -192,6 +200,14 @@ export function useSelect<TG extends Select>(
|
|
|
192
200
|
instance.keydown(event, rootElement.value);
|
|
193
201
|
};
|
|
194
202
|
|
|
203
|
+
const selectClear = () => {
|
|
204
|
+
// trigger input for non-autocomplete selects
|
|
205
|
+
// it is already automatically triggered for autocomplete selects
|
|
206
|
+
if (!instance.autocomplete) {
|
|
207
|
+
textInputScope.input();
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
195
211
|
const autoSelectFirst = computed(() => instance.autoSelection && items.value.length === 1);
|
|
196
212
|
|
|
197
213
|
const menuClass = computed(() => {
|
|
@@ -222,6 +238,7 @@ export function useSelect<TG extends Select>(
|
|
|
222
238
|
selectChange,
|
|
223
239
|
selectInput,
|
|
224
240
|
selectKeydown,
|
|
241
|
+
selectClear,
|
|
225
242
|
hasItemBeforeSlot,
|
|
226
243
|
hasItemAfterSlot,
|
|
227
244
|
onLoadMoreIntersect,
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
@mouseleave="mouseleave($event)"
|
|
75
75
|
@click="click($event)"
|
|
76
76
|
@update:modelValue="selectChange($event)"
|
|
77
|
+
@click:clear="selectClear()"
|
|
77
78
|
@blur="blur($event)"
|
|
78
79
|
@focus="focus($event)"
|
|
79
80
|
@update:search="selectInput($event)"
|
|
@@ -178,7 +179,7 @@
|
|
|
178
179
|
min-height: 22px;
|
|
179
180
|
padding: 0;
|
|
180
181
|
}
|
|
181
|
-
|
|
182
|
+
|
|
182
183
|
.v-field__input {
|
|
183
184
|
padding: 0;
|
|
184
185
|
min-height: 34px;
|
|
@@ -207,4 +208,4 @@
|
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
|
-
</style>
|
|
211
|
+
</style>
|
|
@@ -6,6 +6,7 @@ import { buildProps } from '../../utils';
|
|
|
6
6
|
import { getRootElement } from '../zd-component/ZdComponent';
|
|
7
7
|
import { useCreateInputInstance } from '../zd-input/ZdInput';
|
|
8
8
|
import { ZdSelectProps, useSelect } from '../zd-select/ZdSelect';
|
|
9
|
+
import { ListItem } from 'vuetify/lib/composables/list-items';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Select Multiple component
|
|
@@ -330,12 +331,12 @@ const selectMultipleComponent: any = defineComponent({
|
|
|
330
331
|
return selectFormatterFn(item, formatterProps);
|
|
331
332
|
};
|
|
332
333
|
|
|
333
|
-
const removeItem = (item:
|
|
334
|
+
const removeItem = (item: ListItem<any>) => {
|
|
334
335
|
const rootValue = root.value as VSelect;
|
|
335
|
-
rootValue.select(item
|
|
336
|
+
rootValue.select(item, false);
|
|
336
337
|
};
|
|
337
338
|
|
|
338
|
-
const selectChange = (value: any, event
|
|
339
|
+
const selectChange = (value: any[], event?: Event) => {
|
|
339
340
|
const input = getRootElement(root);
|
|
340
341
|
|
|
341
342
|
instance.selectChange(
|
|
@@ -345,6 +346,22 @@ const selectMultipleComponent: any = defineComponent({
|
|
|
345
346
|
);
|
|
346
347
|
};
|
|
347
348
|
|
|
349
|
+
const selectClear = () => {
|
|
350
|
+
const input = getRootElement(root);
|
|
351
|
+
const hasSelectedValue = Array.isArray(instance.value) && instance.value.length > 0;
|
|
352
|
+
const hasSearchText = !!instance.search;
|
|
353
|
+
|
|
354
|
+
if (hasSelectedValue) {
|
|
355
|
+
instance.selectChange([], undefined, input.value);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (hasSearchText) {
|
|
359
|
+
selectScope.selectInput('');
|
|
360
|
+
} else {
|
|
361
|
+
instance.search = '';
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
|
|
348
365
|
let observer: ResizeObserver | undefined;
|
|
349
366
|
|
|
350
367
|
onMounted(() => {
|
|
@@ -381,6 +398,7 @@ const selectMultipleComponent: any = defineComponent({
|
|
|
381
398
|
selectClick,
|
|
382
399
|
selectBlur,
|
|
383
400
|
selectChange,
|
|
401
|
+
selectClear,
|
|
384
402
|
formattedDataDiscreteText,
|
|
385
403
|
ajustSize,
|
|
386
404
|
onLoadMoreIntersect,
|
|
@@ -80,6 +80,15 @@
|
|
|
80
80
|
@keydown="instance.keydown($event)"
|
|
81
81
|
v-on="getIconClickEvents()"
|
|
82
82
|
>
|
|
83
|
+
<template #clear="{ props }">
|
|
84
|
+
<v-icon
|
|
85
|
+
:tabindex="props.tabindex"
|
|
86
|
+
@focus="props.onFocus"
|
|
87
|
+
@blur="props.onBlur"
|
|
88
|
+
@click="selectClear"
|
|
89
|
+
></v-icon>
|
|
90
|
+
</template>
|
|
91
|
+
|
|
83
92
|
<template #prepend-item v-if="instance.itemBeforeSlot.length || instance.showSelectAll">
|
|
84
93
|
<template v-if="instance.showSelectAll">
|
|
85
94
|
<v-list-item
|
|
@@ -297,4 +306,4 @@
|
|
|
297
306
|
.zd-select__menu .v-list-item-title, .zd-select__menu .v-list-item__content {
|
|
298
307
|
font-size: var(--zd-font-body1-size);
|
|
299
308
|
}
|
|
300
|
-
</style>
|
|
309
|
+
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Tab } from '@zeedhi/common';
|
|
1
|
+
import { Tab, Tabs } from '@zeedhi/common';
|
|
2
2
|
import { Event } from '@zeedhi/core';
|
|
3
|
-
import { defineComponent } from 'vue';
|
|
3
|
+
import { computed, defineComponent, ref } from 'vue';
|
|
4
4
|
import { useDensity } from '../../composables';
|
|
5
5
|
import { buildProps } from '../../utils';
|
|
6
6
|
import { useCreateInstance, useGetMethods } from '../zd-component/ZdComponent';
|
|
@@ -15,9 +15,6 @@ export const ZdTabProps = buildProps({
|
|
|
15
15
|
tabTitle: {
|
|
16
16
|
type: [String],
|
|
17
17
|
},
|
|
18
|
-
tabName: {
|
|
19
|
-
type: [String],
|
|
20
|
-
},
|
|
21
18
|
color: {
|
|
22
19
|
type: [String],
|
|
23
20
|
default: 'primary',
|
|
@@ -70,6 +67,8 @@ const tabComponent = defineComponent({
|
|
|
70
67
|
|
|
71
68
|
const { click, focus, blur, mouseenter, mouseleave } = useGetMethods(instance, root);
|
|
72
69
|
|
|
70
|
+
const isDragging = ref<boolean>(false);
|
|
71
|
+
|
|
73
72
|
const clickTab = (event: Event) => {
|
|
74
73
|
ctx.emit('click', event);
|
|
75
74
|
};
|
|
@@ -78,9 +77,43 @@ const tabComponent = defineComponent({
|
|
|
78
77
|
ctx.emit('keydown', event);
|
|
79
78
|
};
|
|
80
79
|
|
|
80
|
+
const sortable = computed(() => {
|
|
81
|
+
return (instance.parent as Tabs)?.sortable;
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const handleDragStart = (event: DragEvent): void => {
|
|
85
|
+
if (!sortable.value) {
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (event.dataTransfer) {
|
|
91
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
92
|
+
|
|
93
|
+
// Compatibilidade Firefox
|
|
94
|
+
event.dataTransfer.setData('text/plain', '');
|
|
95
|
+
|
|
96
|
+
const tabsInstance = instance.parent as Tabs;
|
|
97
|
+
const sourceIndex = tabsInstance.tabs.findIndex((tab) => tab.name === instance.name);
|
|
98
|
+
|
|
99
|
+
event.dataTransfer.setData(`application/x-zd-tabs-owner-${tabsInstance.name.toLowerCase()}`, '');
|
|
100
|
+
event.dataTransfer.setData('application/x-zd-tab-index', String(sourceIndex));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
isDragging.value = true;
|
|
104
|
+
|
|
105
|
+
event.stopPropagation();
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const handleDragEnd = (): void => {
|
|
109
|
+
isDragging.value = false;
|
|
110
|
+
};
|
|
111
|
+
|
|
81
112
|
return {
|
|
82
113
|
instance,
|
|
83
114
|
root,
|
|
115
|
+
density,
|
|
116
|
+
sortable,
|
|
84
117
|
click,
|
|
85
118
|
focus,
|
|
86
119
|
blur,
|
|
@@ -89,7 +122,8 @@ const tabComponent = defineComponent({
|
|
|
89
122
|
// methods
|
|
90
123
|
clickTab,
|
|
91
124
|
keydown,
|
|
92
|
-
|
|
125
|
+
handleDragStart,
|
|
126
|
+
handleDragEnd,
|
|
93
127
|
};
|
|
94
128
|
},
|
|
95
129
|
});
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
:id="instance.name"
|
|
4
4
|
ref="root"
|
|
5
5
|
v-show="instance.isVisible"
|
|
6
|
-
:class="['zd-tabs-tab', instance.cssClass
|
|
6
|
+
:class="['zd-tabs-tab', instance.cssClass, {
|
|
7
|
+
'zd-tabs-tab-sortable': sortable,
|
|
8
|
+
}]"
|
|
7
9
|
:style="$styleObject(instance.cssStyle)"
|
|
8
|
-
:name="instance.
|
|
10
|
+
:name="instance.tabTitle"
|
|
9
11
|
:disabled="instance.disabled"
|
|
10
12
|
:theme="instance.theme"
|
|
11
13
|
:color="instance.color"
|
|
@@ -15,11 +17,14 @@
|
|
|
15
17
|
:iconName="instance.iconName"
|
|
16
18
|
:rounded="instance.rounded"
|
|
17
19
|
:selected-class="'v-tab--selected '+instance.selectedClass"
|
|
18
|
-
:value="instance.value"
|
|
20
|
+
:value="instance.name || instance.value"
|
|
19
21
|
:variant="instance.variant"
|
|
20
22
|
:width="instance.width"
|
|
23
|
+
:draggable="sortable"
|
|
21
24
|
@click="clickTab($event)"
|
|
22
25
|
@keydown="keydown($event)"
|
|
26
|
+
@dragstart="handleDragStart"
|
|
27
|
+
@dragend="handleDragEnd"
|
|
23
28
|
>
|
|
24
29
|
<span class="zd-tabs-tab-text">
|
|
25
30
|
{{ $t(instance.tabTitle) }}
|
|
@@ -46,6 +51,14 @@
|
|
|
46
51
|
line-height: 15px;
|
|
47
52
|
margin-bottom: 1px;
|
|
48
53
|
}
|
|
54
|
+
|
|
55
|
+
&-sortable::before {
|
|
56
|
+
content: "⋮";
|
|
57
|
+
position: absolute;
|
|
58
|
+
left: 1px;
|
|
59
|
+
width: 10px;
|
|
60
|
+
cursor: grab;
|
|
61
|
+
}
|
|
49
62
|
}
|
|
50
63
|
}
|
|
51
64
|
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tabs } from '@zeedhi/common';
|
|
2
|
-
import { defineComponent } from 'vue';
|
|
2
|
+
import { computed, defineComponent, ref } from 'vue';
|
|
3
3
|
import { useDensity } from '../../composables';
|
|
4
4
|
import { HeightProps } from '../../propsMixins/heightProps';
|
|
5
5
|
import { buildProps } from '../../utils';
|
|
@@ -45,6 +45,10 @@ export const ZdTabsProps = buildProps({
|
|
|
45
45
|
max: {
|
|
46
46
|
type: [Number, String],
|
|
47
47
|
},
|
|
48
|
+
sortable: {
|
|
49
|
+
type: [Boolean, String],
|
|
50
|
+
default: false,
|
|
51
|
+
},
|
|
48
52
|
});
|
|
49
53
|
|
|
50
54
|
/**
|
|
@@ -56,9 +60,13 @@ const tabsComponent = defineComponent({
|
|
|
56
60
|
setup(props, ctx) {
|
|
57
61
|
const { instance, root } = useCreateInstance<Tabs>(props, ctx, Tabs, ZdTabsProps);
|
|
58
62
|
const { density } = useDensity({ instance });
|
|
63
|
+
const rootElement = getRootElement(root);
|
|
59
64
|
|
|
60
65
|
const { click, focus, blur, mouseenter, mouseleave } = useGetMethods(instance, root);
|
|
61
66
|
|
|
67
|
+
const isDragOver = ref<boolean>(false);
|
|
68
|
+
const dragOverIndex = ref<number>(-1);
|
|
69
|
+
|
|
62
70
|
const change = () => {
|
|
63
71
|
const rootElement = getRootElement(root);
|
|
64
72
|
instance.change(new Event('change'), rootElement.value);
|
|
@@ -73,10 +81,93 @@ const tabsComponent = defineComponent({
|
|
|
73
81
|
const rootElement = getRootElement(root);
|
|
74
82
|
instance.beforeChange(event, index, rootElement.value);
|
|
75
83
|
};
|
|
84
|
+
|
|
85
|
+
const isTabOK = (event: DragEvent): boolean => {
|
|
86
|
+
return !!event.dataTransfer?.types.includes(`application/x-zd-tabs-owner-${instance.name.toLowerCase()}`);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const getTabsBarRect = (): DOMRect | undefined => {
|
|
90
|
+
return rootElement.value?.querySelector('.v-tabs')?.getBoundingClientRect();
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const handleDragOver = (event: DragEvent): void => {
|
|
94
|
+
event.preventDefault();
|
|
95
|
+
|
|
96
|
+
if (!isTabOK(event)) {
|
|
97
|
+
dragOverIndex.value = -1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const tabsRect = getTabsBarRect();
|
|
102
|
+
if (!tabsRect) return;
|
|
103
|
+
|
|
104
|
+
if (event.clientY < tabsRect.top - 10 || event.clientY > tabsRect.bottom + 10) {
|
|
105
|
+
dragOverIndex.value = -1;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const tabs = rootElement.value!.querySelectorAll('.zd-tabs-tab');
|
|
110
|
+
let targetIndex = instance.tabs.length;
|
|
111
|
+
|
|
112
|
+
tabs.forEach((tabEl, index) => {
|
|
113
|
+
const rect = tabEl.getBoundingClientRect();
|
|
114
|
+
|
|
115
|
+
if (event.clientX < rect.left + rect.width / 2) {
|
|
116
|
+
targetIndex = Math.min(targetIndex, index);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
dragOverIndex.value = targetIndex;
|
|
121
|
+
event.stopPropagation();
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const handleDrop = (event: DragEvent): void => {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
|
|
127
|
+
if (!isTabOK(event) || dragOverIndex.value === -1) return;
|
|
128
|
+
|
|
129
|
+
event.stopPropagation();
|
|
130
|
+
|
|
131
|
+
const sourceIndex = Number(event.dataTransfer?.getData('application/x-zd-tab-index'));
|
|
132
|
+
instance.moveTab(sourceIndex, dragOverIndex.value);
|
|
133
|
+
|
|
134
|
+
isDragOver.value = false;
|
|
135
|
+
dragOverIndex.value = -1;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const handleDragEnter = (event: DragEvent): void => {
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
|
|
141
|
+
if (!isTabOK(event)) {
|
|
142
|
+
isDragOver.value = false;
|
|
143
|
+
dragOverIndex.value = -1;
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
isDragOver.value = true;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handleDragLeave = (event: DragEvent): void => {
|
|
151
|
+
if (rootElement.value && event.relatedTarget && rootElement.value.contains(event.relatedTarget as Node)) return;
|
|
152
|
+
|
|
153
|
+
isDragOver.value = false;
|
|
154
|
+
dragOverIndex.value = -1;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const activeTabName = computed<string | undefined>({
|
|
158
|
+
get: () => instance.tabs[instance.activeTab]?.name,
|
|
159
|
+
set: (name) => {
|
|
160
|
+
const index = instance.tabs.findIndex((tab) => tab.name === name);
|
|
161
|
+
if (index !== -1) instance.activeTab = index;
|
|
162
|
+
},
|
|
163
|
+
});
|
|
76
164
|
|
|
77
165
|
return {
|
|
78
166
|
instance,
|
|
79
167
|
root,
|
|
168
|
+
dragOverIndex,
|
|
169
|
+
density,
|
|
170
|
+
activeTabName,
|
|
80
171
|
click,
|
|
81
172
|
focus,
|
|
82
173
|
blur,
|
|
@@ -85,7 +176,10 @@ const tabsComponent = defineComponent({
|
|
|
85
176
|
clickTab,
|
|
86
177
|
keydown,
|
|
87
178
|
change,
|
|
88
|
-
|
|
179
|
+
handleDragOver,
|
|
180
|
+
handleDrop,
|
|
181
|
+
handleDragEnter,
|
|
182
|
+
handleDragLeave,
|
|
89
183
|
};
|
|
90
184
|
},
|
|
91
185
|
});
|
|
@@ -10,9 +10,13 @@
|
|
|
10
10
|
maxHeight: instance.maxHeight,
|
|
11
11
|
minHeight:instance.minHeight,
|
|
12
12
|
}"
|
|
13
|
+
@dragenter="handleDragEnter"
|
|
14
|
+
@dragleave="handleDragLeave"
|
|
15
|
+
@dragover="handleDragOver"
|
|
16
|
+
@drop="handleDrop"
|
|
13
17
|
>
|
|
14
18
|
<v-tabs
|
|
15
|
-
v-model="
|
|
19
|
+
v-model="activeTabName"
|
|
16
20
|
show-arrows
|
|
17
21
|
@update:model-value="change"
|
|
18
22
|
:theme="instance.theme"
|
|
@@ -24,31 +28,39 @@
|
|
|
24
28
|
:grow="instance.grow"
|
|
25
29
|
:max="instance.max"
|
|
26
30
|
>
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
<template v-for="(tab, index) in instance.tabs " :key="tab.name">
|
|
32
|
+
<span
|
|
33
|
+
v-if="dragOverIndex === index"
|
|
34
|
+
class="zd-tabs-sortable-drop-indicator"
|
|
35
|
+
/>
|
|
36
|
+
|
|
37
|
+
<zd-tab
|
|
38
|
+
v-bind="{
|
|
39
|
+
...tab,
|
|
40
|
+
name: tab.name,
|
|
41
|
+
dense: tab.dense || instance.dense,
|
|
42
|
+
}"
|
|
43
|
+
@click="clickTab($event, index)"
|
|
44
|
+
@keydown="keydown($event, index)"
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<span
|
|
49
|
+
v-if="dragOverIndex === instance.tabs.length"
|
|
50
|
+
class="zd-tabs-sortable-drop-indicator"
|
|
51
|
+
/>
|
|
39
52
|
</v-tabs>
|
|
40
53
|
|
|
41
54
|
<v-window
|
|
42
|
-
|
|
55
|
+
:model-value="activeTabName"
|
|
43
56
|
>
|
|
44
57
|
<zd-tab-item
|
|
45
58
|
v-for="(tab, index) in instance.tabs"
|
|
46
|
-
v-show="tab.isVisible &&
|
|
59
|
+
v-show="tab.isVisible && tab.name === activeTabName"
|
|
47
60
|
:key="tab.name"
|
|
48
|
-
:value="
|
|
61
|
+
:value="tab.name"
|
|
49
62
|
:children ="tab.children"
|
|
50
63
|
v-bind ="{
|
|
51
|
-
index: index,
|
|
52
64
|
name: instance.name+'-tab-item-'+index,
|
|
53
65
|
lazyLoad: tab.lazyLoad,
|
|
54
66
|
}"
|
|
@@ -113,5 +125,22 @@
|
|
|
113
125
|
height:100% !important;
|
|
114
126
|
}
|
|
115
127
|
}
|
|
128
|
+
|
|
129
|
+
&-sortable-drop-indicator {
|
|
130
|
+
display: inline-block;
|
|
131
|
+
position: relative;
|
|
132
|
+
height: 100%;
|
|
133
|
+
width: 0;
|
|
134
|
+
z-index: 1;
|
|
135
|
+
|
|
136
|
+
&::after {
|
|
137
|
+
content: '';
|
|
138
|
+
width: 3px;
|
|
139
|
+
background-color: var(--v-primary-base);
|
|
140
|
+
height: 100%;
|
|
141
|
+
position: absolute;
|
|
142
|
+
opacity: 0.75;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
116
145
|
}
|
|
117
146
|
</style>
|
|
@@ -171,6 +171,11 @@ export function useTextInput<TG extends TextInput>(
|
|
|
171
171
|
});
|
|
172
172
|
};
|
|
173
173
|
|
|
174
|
+
const clearInput = () => {
|
|
175
|
+
inputScope.input();
|
|
176
|
+
inputScope.change();
|
|
177
|
+
};
|
|
178
|
+
|
|
174
179
|
const getIconClickEvents = () => {
|
|
175
180
|
const events: any = {};
|
|
176
181
|
if (instance.events.appendIconClick) {
|
|
@@ -207,6 +212,7 @@ export function useTextInput<TG extends TextInput>(
|
|
|
207
212
|
appendOuterIconClick,
|
|
208
213
|
prependOuterIconClick,
|
|
209
214
|
setBlur,
|
|
215
|
+
clearInput,
|
|
210
216
|
getIconClickEvents,
|
|
211
217
|
};
|
|
212
218
|
}
|