srcdev-nuxt-components 1.0.3 → 1.1.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/components/functional/display-dialog/DisplayDialogCore.vue +5 -1
- package/components/functional/display-dialog/variants/DisplayDialogConfirm.vue +5 -1
- package/components/functional/display-dialog/variants/DisplayDialogScrollableContent.vue +5 -1
- package/components/presentation/tabs/TabsCore.vue +11 -3
- package/composables/useDialogControls.ts +23 -0
- package/composables/useTabs.ts +36 -5
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<dialog class="display-dialog-core" :class="[variant, elementClasses]" :align-dialog :open ref="dialogRef">
|
|
2
|
+
<dialog class="display-dialog-core" :class="[variant, elementClasses]" role="dialog" :align-dialog :open :data-dialog-id="dataDialogId" ref="dialogRef">
|
|
3
3
|
<focus-trap v-model:active="open" :clickOutsideDeactivates="true" @deactivate="closeDialog()">
|
|
4
4
|
<div class="inner">
|
|
5
5
|
<div class="header">
|
|
@@ -58,6 +58,10 @@ const props = defineProps({
|
|
|
58
58
|
type: Boolean,
|
|
59
59
|
default: false,
|
|
60
60
|
},
|
|
61
|
+
dataDialogId: {
|
|
62
|
+
type: String,
|
|
63
|
+
required: true,
|
|
64
|
+
},
|
|
61
65
|
});
|
|
62
66
|
|
|
63
67
|
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<DisplayDialogCore variant="confirm" :styleClassPassthrough :lockViewport="true">
|
|
2
|
+
<DisplayDialogCore variant="confirm" :styleClassPassthrough :lockViewport="true" :dataDialogId>
|
|
3
3
|
<template #dialogTitle>
|
|
4
4
|
<slot name="dialogTitle">
|
|
5
5
|
<p class="text-normal wght-700">Confirm</p>
|
|
@@ -21,6 +21,10 @@ const props = defineProps({
|
|
|
21
21
|
type: Array as PropType<string[]>,
|
|
22
22
|
default: () => [],
|
|
23
23
|
},
|
|
24
|
+
dataDialogId: {
|
|
25
|
+
type: String,
|
|
26
|
+
required: true,
|
|
27
|
+
},
|
|
24
28
|
});
|
|
25
29
|
</script>
|
|
26
30
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<DisplayDialogCore variant="dialog" :styleClassPassthrough :lockViewport="true" :allowContentScroll>
|
|
2
|
+
<DisplayDialogCore variant="dialog" :styleClassPassthrough :lockViewport="true" :allowContentScroll :dataDialogId>
|
|
3
3
|
<template #dialogTitle>
|
|
4
4
|
<slot name="dialogTitle">
|
|
5
5
|
<p class="text-normal wght-700">Confirm</p>
|
|
@@ -25,6 +25,10 @@ const props = defineProps({
|
|
|
25
25
|
type: Boolean,
|
|
26
26
|
default: false,
|
|
27
27
|
},
|
|
28
|
+
dataDialogId: {
|
|
29
|
+
type: String,
|
|
30
|
+
required: true,
|
|
31
|
+
},
|
|
28
32
|
});
|
|
29
33
|
</script>
|
|
30
34
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
@click.prevent="navItemClicked($event)"
|
|
7
7
|
@mouseover="navItemHovered($event)"
|
|
8
8
|
:id="`tab-${key}-trigger`"
|
|
9
|
-
:data-tab-index="
|
|
9
|
+
:data-tab-index="key"
|
|
10
10
|
data-nav-item
|
|
11
11
|
role="tab"
|
|
12
12
|
aria-selected="false"
|
|
@@ -32,6 +32,10 @@ const props = defineProps({
|
|
|
32
32
|
type: String as PropType<string>,
|
|
33
33
|
default: 'button',
|
|
34
34
|
},
|
|
35
|
+
transitionDuration: {
|
|
36
|
+
type: Number as PropType<number>,
|
|
37
|
+
default: 200,
|
|
38
|
+
},
|
|
35
39
|
navItems: {
|
|
36
40
|
type: Array as PropType<ITabNav[]>,
|
|
37
41
|
required: true,
|
|
@@ -59,7 +63,7 @@ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
|
|
|
59
63
|
const tabsNavRef = ref<HTMLElement | null>(null);
|
|
60
64
|
const tabsContentRefs = ref<HTMLElement[] | null>(null);
|
|
61
65
|
|
|
62
|
-
const { initNavDecorators, navItemClicked, navItemHovered, resetHoverToActivePosition } = useTabs(tabsNavRef, tabsContentRefs);
|
|
66
|
+
const { initNavDecorators, navItemClicked, navItemHovered, resetHoverToActivePosition } = useTabs(tabsNavRef, tabsContentRefs, props.transitionDuration);
|
|
63
67
|
|
|
64
68
|
onMounted(() => {
|
|
65
69
|
initNavDecorators();
|
|
@@ -140,7 +144,7 @@ onMounted(() => {
|
|
|
140
144
|
.tabs-list-item {
|
|
141
145
|
opacity: 0.7;
|
|
142
146
|
position: relative;
|
|
143
|
-
transition: color
|
|
147
|
+
transition: color 100ms;
|
|
144
148
|
z-index: 4;
|
|
145
149
|
|
|
146
150
|
&:hover {
|
|
@@ -187,6 +191,10 @@ onMounted(() => {
|
|
|
187
191
|
&[aria-selected='true'] {
|
|
188
192
|
color: var(--_tabs-active-text);
|
|
189
193
|
}
|
|
194
|
+
|
|
195
|
+
&.transitioning {
|
|
196
|
+
color: var(--_tabs-hovered-text);
|
|
197
|
+
}
|
|
190
198
|
}
|
|
191
199
|
}
|
|
192
200
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const useDialogControls = () => {
|
|
2
|
+
interface DialogConfig {
|
|
3
|
+
[key: string]: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const dialogsConfig = reactive<DialogConfig>({});
|
|
7
|
+
|
|
8
|
+
function initialiseDialogs(dialogIds: string[]) {
|
|
9
|
+
dialogIds.forEach((id) => {
|
|
10
|
+
dialogsConfig[id] = false;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const controlDialogs = (name: string, state: boolean) => {
|
|
15
|
+
dialogsConfig[name] = state;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
dialogsConfig,
|
|
20
|
+
controlDialogs,
|
|
21
|
+
initialiseDialogs,
|
|
22
|
+
};
|
|
23
|
+
};
|
package/composables/useTabs.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useResizeObserver } from '@vueuse/core';
|
|
2
2
|
|
|
3
|
-
const useTabs = (tabsNavRef: Ref<HTMLElement | null>, tabsContentRefs: Ref<HTMLElement[] | null>, duration: number
|
|
3
|
+
const useTabs = (tabsNavRef: Ref<HTMLElement | null>, tabsContentRefs: Ref<HTMLElement[] | null>, duration: number) => {
|
|
4
4
|
const navItems = ref<HTMLElement[] | null>(null);
|
|
5
5
|
const previousActiveTab = useState<HTMLElement | null>('previousActiveTab', () => null);
|
|
6
6
|
const currentActiveTab = ref<HTMLElement>();
|
|
@@ -79,6 +79,37 @@ const useTabs = (tabsNavRef: Ref<HTMLElement | null>, tabsContentRefs: Ref<HTMLE
|
|
|
79
79
|
setActiveTabContent();
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
const handleTransitioningClass = (transitionDuration: number = 200) => {
|
|
83
|
+
if (previousHoveredTab.value && currentHoveredTab.value) {
|
|
84
|
+
const newTabPosition = previousHoveredTab.value.compareDocumentPosition(currentHoveredTab.value);
|
|
85
|
+
const navItemsArray = navItems.value || [];
|
|
86
|
+
|
|
87
|
+
const timeout = Math.floor(transitionDuration / Math.abs(navItemsArray.indexOf(currentHoveredTab.value) - navItemsArray.indexOf(previousHoveredTab.value)));
|
|
88
|
+
|
|
89
|
+
if (newTabPosition === 4) {
|
|
90
|
+
for (let i = navItemsArray.indexOf(previousHoveredTab.value); i < navItemsArray.indexOf(currentHoveredTab.value); i++) {
|
|
91
|
+
navItemsArray[i].classList.add('transitioning');
|
|
92
|
+
if (i >= navItemsArray.indexOf(previousHoveredTab.value) && i < navItemsArray.indexOf(currentHoveredTab.value)) {
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
navItemsArray[i].classList.remove('transitioning');
|
|
95
|
+
// }, timeout * (i - navItemsArray.indexOf(previousHoveredTab.value) - 1));
|
|
96
|
+
}, duration * 1.5);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
for (let i = navItemsArray.indexOf(previousHoveredTab.value); i > navItemsArray.indexOf(currentHoveredTab.value); i--) {
|
|
101
|
+
navItemsArray[i].classList.add('transitioning');
|
|
102
|
+
if (i <= navItemsArray.indexOf(previousHoveredTab.value) && i > navItemsArray.indexOf(currentHoveredTab.value)) {
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
navItemsArray[i].classList.remove('transitioning');
|
|
105
|
+
// }, timeout * (i - navItemsArray.indexOf(previousHoveredTab.value) - 1));
|
|
106
|
+
}, duration * 1.5);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
82
113
|
const setFinalHoveredPositions = (resized: boolean = false) => {
|
|
83
114
|
const setDuration = resized ? 0 : duration;
|
|
84
115
|
const newTabWidth = currentHoveredTab.value && tabsNavRef.value ? currentHoveredTab.value.offsetWidth / tabsNavRef.value.offsetWidth : 0;
|
|
@@ -110,6 +141,8 @@ const useTabs = (tabsNavRef: Ref<HTMLElement | null>, tabsContentRefs: Ref<HTMLE
|
|
|
110
141
|
|
|
111
142
|
tabsNavRef.value?.style.setProperty('--_width-active', String(transitionWidth / tabsNavRef.value.offsetWidth));
|
|
112
143
|
|
|
144
|
+
handleTransitioningClass(duration);
|
|
145
|
+
|
|
113
146
|
setTimeout(() => {
|
|
114
147
|
setFinalActivePositions();
|
|
115
148
|
}, Math.floor(duration + 20));
|
|
@@ -130,6 +163,8 @@ const useTabs = (tabsNavRef: Ref<HTMLElement | null>, tabsContentRefs: Ref<HTMLE
|
|
|
130
163
|
|
|
131
164
|
tabsNavRef.value?.style.setProperty('--_width-hovered', String(transitionWidth / tabsNavRef.value.offsetWidth));
|
|
132
165
|
|
|
166
|
+
handleTransitioningClass(duration);
|
|
167
|
+
|
|
133
168
|
setTimeout(() => {
|
|
134
169
|
setFinalHoveredPositions();
|
|
135
170
|
}, Math.floor(duration + 20));
|
|
@@ -142,10 +177,6 @@ const useTabs = (tabsNavRef: Ref<HTMLElement | null>, tabsContentRefs: Ref<HTMLE
|
|
|
142
177
|
});
|
|
143
178
|
};
|
|
144
179
|
|
|
145
|
-
const animationRunning = (running: boolean) => {
|
|
146
|
-
console.log('animationRunning', running);
|
|
147
|
-
};
|
|
148
|
-
|
|
149
180
|
useResizeObserver(tabsNavRef, () => {
|
|
150
181
|
setFinalActivePositions(true);
|
|
151
182
|
setFinalHoveredPositions(true);
|
package/package.json
CHANGED