@policystudio/policy-studio-ui-vue 1.1.90-beta.75 → 1.1.90-beta.76
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.
|
@@ -4013,21 +4013,9 @@ video {
|
|
|
4013
4013
|
min-height: 27px;
|
|
4014
4014
|
font-size: 0.875rem;
|
|
4015
4015
|
}
|
|
4016
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4017
|
-
position: fixed;
|
|
4018
|
-
}
|
|
4019
4016
|
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4020
4017
|
z-index: 50;
|
|
4021
4018
|
}
|
|
4022
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4023
|
-
display: none;
|
|
4024
|
-
}
|
|
4025
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4026
|
-
width: auto;
|
|
4027
|
-
}
|
|
4028
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4029
|
-
transform-origin: top right;
|
|
4030
|
-
}
|
|
4031
4019
|
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4032
4020
|
overflow: auto;
|
|
4033
4021
|
}
|
|
@@ -4038,28 +4026,11 @@ video {
|
|
|
4038
4026
|
--tw-bg-opacity: 1;
|
|
4039
4027
|
background-color: rgb(255, 255, 255, var(--tw-bg-opacity, 1));
|
|
4040
4028
|
}
|
|
4041
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4042
|
-
opacity: 0;
|
|
4043
|
-
}
|
|
4044
4029
|
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4045
4030
|
--tw-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04), 0px 5px 6px rgba(0, 0, 0, 0.1);
|
|
4046
4031
|
--tw-shadow-colored: 0px 0px 8px var(--tw-shadow-color), 0px 5px 6px var(--tw-shadow-color);
|
|
4047
4032
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-ring-shadow, 0 0 rgba(0, 0, 0, 0)), var(--tw-shadow);
|
|
4048
4033
|
}
|
|
4049
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4050
|
-
transition-property: opacity;
|
|
4051
|
-
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
4052
|
-
transition-duration: 150ms;
|
|
4053
|
-
}
|
|
4054
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4055
|
-
transition-duration: 100ms;
|
|
4056
|
-
}
|
|
4057
|
-
.psui-el-dropdown-menu-dialog-wrapper {
|
|
4058
|
-
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
|
4059
|
-
}
|
|
4060
|
-
.psui-el-dropdown-menu-dialog-wrapper-dialog {
|
|
4061
|
-
width: 100%;
|
|
4062
|
-
}
|
|
4063
4034
|
|
|
4064
4035
|
.psui-el-dropdown-menu-list {
|
|
4065
4036
|
margin-top: 1rem;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@policystudio/policy-studio-ui-vue",
|
|
3
|
-
"version": "1.1.90-beta.
|
|
3
|
+
"version": "1.1.90-beta.76",
|
|
4
4
|
"description": "Policy Studio UI",
|
|
5
5
|
"author": "Policy Studio Team",
|
|
6
6
|
"scripts": {
|
|
@@ -15,10 +15,12 @@
|
|
|
15
15
|
"main": "dist/index.js",
|
|
16
16
|
"types": "src/types/index.d.ts",
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"@floating-ui/vue": "^1.1.9",
|
|
18
19
|
"@vue/compat": "^3.4.5",
|
|
19
20
|
"core-js": "^3.6.5",
|
|
20
21
|
"v-tooltip": "^2.1.3",
|
|
21
|
-
"vue": "^3.4.5"
|
|
22
|
+
"vue": "^3.4.5",
|
|
23
|
+
"vue2-teleport": "^1.1.4"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
24
26
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
|
@@ -13,11 +13,7 @@
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
&-dialog-wrapper {
|
|
16
|
-
@apply psui-
|
|
17
|
-
|
|
18
|
-
&-dialog {
|
|
19
|
-
@apply psui-w-full;
|
|
20
|
-
}
|
|
16
|
+
@apply psui-bg-white psui-rounded-md psui-z-50 psui-shadow-elevation-20 psui-overflow-auto;
|
|
21
17
|
}
|
|
22
18
|
}
|
|
23
19
|
}
|
|
@@ -1,212 +1,120 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
ref="PSDropdown"
|
|
4
3
|
class="psui-el-dropdown-menu"
|
|
5
|
-
:class="{ 'is-open': show.value }"
|
|
6
|
-
v-click-outside="close"
|
|
7
4
|
>
|
|
8
5
|
<div
|
|
9
6
|
ref="PSDropdownTrigger"
|
|
10
|
-
|
|
11
|
-
@click="show && !toggleWhenActive ? '' : toggle($event)"
|
|
12
|
-
>
|
|
13
|
-
<slot name="dropdownTrigger" />
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<button
|
|
17
|
-
v-else
|
|
18
|
-
@click="show && !toggleWhenActive ? '' : toggle($event)"
|
|
19
|
-
type="button"
|
|
20
|
-
:id="id.value"
|
|
21
|
-
aria-haspopup="true"
|
|
22
|
-
aria-expanded="true"
|
|
23
|
-
ref="PSDropdownTrigger"
|
|
7
|
+
@click="toggle"
|
|
24
8
|
>
|
|
25
9
|
<slot
|
|
26
|
-
v-if="
|
|
27
|
-
name="
|
|
10
|
+
v-if="$slots.dropdownTrigger"
|
|
11
|
+
name="dropdownTrigger"
|
|
28
12
|
/>
|
|
29
|
-
<
|
|
13
|
+
<button
|
|
30
14
|
v-else
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<slot name="items" />
|
|
44
|
-
</div>
|
|
15
|
+
type="button"
|
|
16
|
+
:aria-expanded="show"
|
|
17
|
+
>
|
|
18
|
+
<slot
|
|
19
|
+
v-if="show && $slots.buttonLabelOnShow"
|
|
20
|
+
name="buttonLabelOnShow"
|
|
21
|
+
/>
|
|
22
|
+
<slot
|
|
23
|
+
v-else
|
|
24
|
+
name="buttonLabel"
|
|
25
|
+
/>
|
|
26
|
+
</button>
|
|
45
27
|
</div>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<Teleport to="body">
|
|
31
|
+
<Transition name="fade">
|
|
32
|
+
<div
|
|
33
|
+
v-if="show"
|
|
34
|
+
ref="PSDropdownFloating"
|
|
35
|
+
role="menu"
|
|
36
|
+
class="psui-el-dropdown-menu-dialog-wrapper"
|
|
37
|
+
aria-orientation="vertical"
|
|
38
|
+
:style="floatingStyles"
|
|
39
|
+
v-click-outside="close"
|
|
40
|
+
>
|
|
41
|
+
<div class="psui-el-dropdown-menu-dialog">
|
|
42
|
+
<slot name="items" />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</Transition>
|
|
46
|
+
</Teleport>
|
|
46
47
|
</div>
|
|
47
48
|
</template>
|
|
48
49
|
|
|
49
50
|
<script setup>
|
|
50
51
|
// Figma - 2.3 Dropdown with category divider https://www.figma.com/file/Tto8hrNlSfuPcwd1pfqogF/%E2%9A%A1%EF%B8%8F-Design-System?node-id=1768%3A64886
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
import {
|
|
53
|
+
useFloating,
|
|
54
|
+
autoUpdate,
|
|
55
|
+
offset,
|
|
56
|
+
flip,
|
|
57
|
+
shift,
|
|
58
|
+
size
|
|
59
|
+
} from '@floating-ui/vue'
|
|
60
|
+
|
|
61
|
+
import { ref, defineProps } from 'vue'
|
|
62
|
+
import Teleport from 'vue2-teleport'
|
|
60
63
|
|
|
61
64
|
const props = defineProps({
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
type:
|
|
67
|
-
default:
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* It's a boolean responsible for showing a slot within the html tag button.
|
|
71
|
-
*/
|
|
72
|
-
buttonLabelOnShow: {
|
|
73
|
-
type: Boolean,
|
|
74
|
-
default: false,
|
|
75
|
-
},
|
|
76
|
-
/**
|
|
77
|
-
* It's a property responsible for toggling the dropdown menu. default: true.
|
|
78
|
-
*/
|
|
79
|
-
toggleWhenActive: {
|
|
80
|
-
type: Boolean,
|
|
81
|
-
default: true,
|
|
82
|
-
},
|
|
83
|
-
/**
|
|
84
|
-
* Disable the toogle on click. default: false.
|
|
85
|
-
*/
|
|
86
|
-
disabled: {
|
|
87
|
-
type: Boolean,
|
|
88
|
-
default: false,
|
|
89
|
-
},
|
|
90
|
-
/**
|
|
91
|
-
* It sets the vertical and horizontal position.
|
|
92
|
-
*/
|
|
93
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment, vue/require-default-prop
|
|
94
|
-
position: {
|
|
95
|
-
type: String,
|
|
96
|
-
validator: (value) => ['custom'].includes(value),
|
|
97
|
-
},
|
|
65
|
+
disabled: {type: Boolean, default: false},
|
|
66
|
+
placement: { type: String, default: 'bottom-start' },
|
|
67
|
+
offsetVal: { type: Number, default: 4 },
|
|
68
|
+
dropdownWidth: {
|
|
69
|
+
type: Number,
|
|
70
|
+
default: null
|
|
71
|
+
}
|
|
98
72
|
})
|
|
99
73
|
|
|
100
74
|
const emit = defineEmits(['open', 'close'])
|
|
101
75
|
|
|
102
76
|
const show = ref(false)
|
|
103
|
-
const id = ref(randomString(8))
|
|
104
|
-
// const marginLeft = ref('-0px')
|
|
105
|
-
const scrollableParentEl = ref(null)
|
|
106
|
-
const PSDropdown = ref(null)
|
|
107
|
-
const PSDropdownDialog = ref(null)
|
|
108
|
-
const PSDropdownTrigger = ref(null)
|
|
109
|
-
|
|
110
|
-
// const getMaxWidth = computed(() => {
|
|
111
|
-
// let bounds = PSDropdown.getBoundingClientRect()
|
|
112
|
-
// return document.documentElement.clientWidth - bounds['left'] - 30
|
|
113
|
-
// })
|
|
114
77
|
|
|
115
|
-
|
|
116
|
-
|
|
78
|
+
const PSDropdownTrigger = ref(null)
|
|
79
|
+
const PSDropdownFloating = ref(null)
|
|
80
|
+
|
|
81
|
+
const { floatingStyles } = useFloating(PSDropdownTrigger, PSDropdownFloating, {
|
|
82
|
+
placement: props.placement,
|
|
83
|
+
whileElementsMounted: autoUpdate,
|
|
84
|
+
middleware: [
|
|
85
|
+
offset(props.offsetVal),
|
|
86
|
+
flip(),
|
|
87
|
+
shift(),
|
|
88
|
+
size({
|
|
89
|
+
apply({rects, elements}) {
|
|
90
|
+
const customWidth = props.dropdownWidth ?? rects.reference.width
|
|
91
|
+
Object.assign(elements.floating.style, {
|
|
92
|
+
width: `${customWidth}px`,
|
|
93
|
+
minWidth: 'fit-content'
|
|
94
|
+
})
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
],
|
|
117
98
|
})
|
|
118
99
|
|
|
119
|
-
const toggle = (event) => {
|
|
120
|
-
if (props.disabled) return
|
|
121
|
-
if (!show.value) {
|
|
122
|
-
open()
|
|
123
|
-
} else {
|
|
124
|
-
close()
|
|
125
|
-
}
|
|
126
|
-
event.stopPropagation()
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const handleEsc = (evt) => {
|
|
130
|
-
if (show.value && evt.keyCode === 27) close()
|
|
131
|
-
}
|
|
132
|
-
|
|
133
100
|
const open = () => {
|
|
134
|
-
emit('open')
|
|
135
101
|
show.value = true
|
|
136
|
-
|
|
137
|
-
PSDropdownDialog.value.style.opacity = 0
|
|
138
|
-
PSDropdownDialog.value.style.display = 'block'
|
|
139
|
-
}
|
|
140
|
-
setTimeout(() => {
|
|
141
|
-
updatePosition()
|
|
142
|
-
watchParentScrolling()
|
|
143
|
-
document.addEventListener('keyup', handleEsc)
|
|
144
|
-
window.addEventListener('resize', updatePosition)
|
|
145
|
-
// window.addEventListener('click', clickOutside)
|
|
146
|
-
}, 10)
|
|
102
|
+
emit('open')
|
|
147
103
|
}
|
|
148
104
|
|
|
149
105
|
const close = () => {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (PSDropdownDialog.value !== null) {
|
|
153
|
-
PSDropdownDialog.value.style.display = 'none'
|
|
154
|
-
PSDropdownDialog.value.style.opacity = 0
|
|
155
|
-
}
|
|
156
|
-
show.value = false
|
|
157
|
-
unwatchParentScrolling()
|
|
158
|
-
}
|
|
159
|
-
document.removeEventListener('keyup', handleEsc)
|
|
160
|
-
document.removeEventListener('resize', updatePosition)
|
|
161
|
-
// document.removeEventListener('click', clickOutside)
|
|
106
|
+
show.value = false
|
|
107
|
+
emit('close')
|
|
162
108
|
}
|
|
163
109
|
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
if (scrollableParentEl.value) {
|
|
167
|
-
scrollableParentEl.value.addEventListener('scroll', updatePosition)
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const unwatchParentScrolling = () => {
|
|
172
|
-
if (scrollableParentEl.value) {
|
|
173
|
-
scrollableParentEl.value.removeEventListener('scroll', updatePosition())
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const updatePosition = () => {
|
|
178
|
-
if (PSDropdownDialog.value === null || PSDropdownTrigger.value === null) return
|
|
179
|
-
|
|
180
|
-
const rectTrigger = PSDropdownTrigger.value.getBoundingClientRect()
|
|
181
|
-
const rectDialog = PSDropdownDialog.value.getBoundingClientRect()
|
|
182
|
-
const windowWidth = document.documentElement.clientWidth
|
|
183
|
-
|
|
184
|
-
PSDropdownDialog.value.style.position = 'fixed'
|
|
185
|
-
PSDropdownDialog.value.style.top = `${rectTrigger.y + rectTrigger.height}px`
|
|
186
|
-
PSDropdownDialog.value.style.minWidth = `${rectTrigger.width}px`
|
|
187
|
-
|
|
188
|
-
if (rectTrigger.x + rectDialog.width + 20 > windowWidth) {
|
|
189
|
-
PSDropdownDialog.value.style.left = `${windowWidth - rectDialog.width - 30}px`
|
|
190
|
-
} else {
|
|
191
|
-
PSDropdownDialog.value.style.left = `${rectTrigger.x}px`
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (props.position == 'custom') {
|
|
195
|
-
PSDropdownDialog.value.style.top = `${rectTrigger.y}px`
|
|
196
|
-
PSDropdownDialog.value.style.left = `${rectTrigger.x + 100}px`
|
|
197
|
-
}
|
|
110
|
+
const toggle = (event) => {
|
|
111
|
+
if (props.disabled) return
|
|
198
112
|
|
|
199
|
-
if (
|
|
200
|
-
close()
|
|
201
|
-
console.warn('The dropdown are too close from the top of the page')
|
|
202
|
-
return
|
|
203
|
-
}
|
|
113
|
+
if (event) event.stopPropagation()
|
|
204
114
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
PSDropdownDialog.value.style.opacity = 1
|
|
208
|
-
}
|
|
209
|
-
}, 10)
|
|
115
|
+
show.value ? close() : open()
|
|
116
|
+
|
|
210
117
|
}
|
|
211
118
|
|
|
119
|
+
defineExpose({ open, close })
|
|
212
120
|
</script>
|